public final class

DrmInitData

extends java.lang.Object

implements java.util.Comparator<DrmInitData.SchemeData>

 java.lang.Object

↳androidx.media3.common.DrmInitData

Gradle dependencies

compile group: 'androidx.media3', name: 'media3-common', version: '1.5.0-alpha01'

  • groupId: androidx.media3
  • artifactId: media3-common
  • version: 1.5.0-alpha01

Artifact androidx.media3:media3-common:1.5.0-alpha01 it located at Google repository (https://maven.google.com/)

Overview

Initialization data for one or more DRM schemes.

Summary

Fields
public static final <any>CREATOR

public final intschemeDataCount

Number of DrmInitData.SchemeDatas.

public final java.lang.StringschemeType

The protection scheme type, or null if not applicable or unknown.

Constructors
publicDrmInitData(DrmInitData.SchemeData schemeDatas[])

publicDrmInitData(java.util.List<DrmInitData.SchemeData> schemeDatas)

publicDrmInitData(java.lang.String schemeType, DrmInitData.SchemeData schemeDatas[])

publicDrmInitData(java.lang.String schemeType, java.util.List<DrmInitData.SchemeData> schemeDatas)

Methods
public intcompare(DrmInitData.SchemeData first, DrmInitData.SchemeData second)

public DrmInitDatacopyWithSchemeType(java.lang.String schemeType)

Returns a copy with the specified protection scheme type.

public static DrmInitDatacreateSessionCreationData(DrmInitData manifestData, DrmInitData mediaData)

Merges DrmInitData obtained from a media manifest and a media stream.

public intdescribeContents()

public booleanequals(java.lang.Object obj)

public DrmInitData.SchemeDataget(int index)

Retrieves the DrmInitData.SchemeData at a given index.

public inthashCode()

public DrmInitDatamerge(DrmInitData drmInitData)

Returns an instance containing the DrmInitData.schemeDatas from both this and other.

public voidwriteToParcel(Parcel dest, int flags)

from java.lang.Objectclone, finalize, getClass, notify, notifyAll, toString, wait, wait, wait

Fields

public final java.lang.String schemeType

The protection scheme type, or null if not applicable or unknown.

public final int schemeDataCount

Number of DrmInitData.SchemeDatas.

public static final <any> CREATOR

Constructors

public DrmInitData(java.util.List<DrmInitData.SchemeData> schemeDatas)

Parameters:

schemeDatas: Scheme initialization data for possibly multiple DRM schemes.

public DrmInitData(java.lang.String schemeType, java.util.List<DrmInitData.SchemeData> schemeDatas)

Parameters:

schemeType: See DrmInitData.schemeType.
schemeDatas: Scheme initialization data for possibly multiple DRM schemes.

public DrmInitData(DrmInitData.SchemeData schemeDatas[])

Parameters:

schemeDatas: Scheme initialization data for possibly multiple DRM schemes.

public DrmInitData(java.lang.String schemeType, DrmInitData.SchemeData schemeDatas[])

Parameters:

schemeType: See DrmInitData.schemeType.
schemeDatas: Scheme initialization data for possibly multiple DRM schemes.

Methods

public static DrmInitData createSessionCreationData(DrmInitData manifestData, DrmInitData mediaData)

Merges DrmInitData obtained from a media manifest and a media stream.

The result is generated as follows.

  1. Include all DrmInitData.SchemeDatas from manifestData where DrmInitData.SchemeData.hasData() is true.
  2. Include all DrmInitData.SchemeDatas in mediaData where DrmInitData.SchemeData.hasData() is true and for which we did not include an entry from the manifest targeting the same UUID.
  3. If available, the scheme type from the manifest is used. If not, the scheme type from the media is used.

Parameters:

manifestData: DRM session acquisition data obtained from the manifest.
mediaData: DRM session acquisition data obtained from the media.

Returns:

A DrmInitData obtained from merging a media manifest and a media stream.

public DrmInitData.SchemeData get(int index)

Retrieves the DrmInitData.SchemeData at a given index.

Parameters:

index: The index of the scheme to return. Must not exceed DrmInitData.schemeDataCount.

Returns:

The DrmInitData.SchemeData at the specified index.

public DrmInitData copyWithSchemeType(java.lang.String schemeType)

Returns a copy with the specified protection scheme type.

Parameters:

schemeType: A protection scheme type. May be null.

Returns:

A copy with the specified protection scheme type.

public DrmInitData merge(DrmInitData drmInitData)

Returns an instance containing the DrmInitData.schemeDatas from both this and other. The DrmInitData.schemeType of the instances being merged must either match, or at least one scheme type must be null.

Parameters:

drmInitData: The instance to merge.

Returns:

The merged result.

public int hashCode()

public boolean equals(java.lang.Object obj)

public int compare(DrmInitData.SchemeData first, DrmInitData.SchemeData second)

public int describeContents()

public void writeToParcel(Parcel dest, int flags)

Source

/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package androidx.media3.common;

import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import androidx.annotation.CheckResult;
import androidx.annotation.Nullable;
import androidx.media3.common.DrmInitData.SchemeData;
import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.UUID;

/** Initialization data for one or more DRM schemes. */
@UnstableApi
public final class DrmInitData implements Comparator<SchemeData>, Parcelable {

  /**
   * Merges {@link DrmInitData} obtained from a media manifest and a media stream.
   *
   * <p>The result is generated as follows.
   *
   * <ol>
   *   <li>Include all {@link SchemeData}s from {@code manifestData} where {@link
   *       SchemeData#hasData()} is true.
   *   <li>Include all {@link SchemeData}s in {@code mediaData} where {@link SchemeData#hasData()}
   *       is true and for which we did not include an entry from the manifest targeting the same
   *       UUID.
   *   <li>If available, the scheme type from the manifest is used. If not, the scheme type from the
   *       media is used.
   * </ol>
   *
   * @param manifestData DRM session acquisition data obtained from the manifest.
   * @param mediaData DRM session acquisition data obtained from the media.
   * @return A {@link DrmInitData} obtained from merging a media manifest and a media stream.
   */
  @Nullable
  public static DrmInitData createSessionCreationData(
      @Nullable DrmInitData manifestData, @Nullable DrmInitData mediaData) {
    ArrayList<SchemeData> result = new ArrayList<>();
    String schemeType = null;
    if (manifestData != null) {
      schemeType = manifestData.schemeType;
      for (SchemeData data : manifestData.schemeDatas) {
        if (data.hasData()) {
          result.add(data);
        }
      }
    }

    if (mediaData != null) {
      if (schemeType == null) {
        schemeType = mediaData.schemeType;
      }
      int manifestDatasCount = result.size();
      for (SchemeData data : mediaData.schemeDatas) {
        if (data.hasData() && !containsSchemeDataWithUuid(result, manifestDatasCount, data.uuid)) {
          result.add(data);
        }
      }
    }

    return result.isEmpty() ? null : new DrmInitData(schemeType, result);
  }

  private final SchemeData[] schemeDatas;

  // Lazily initialized hashcode.
  private int hashCode;

  /** The protection scheme type, or null if not applicable or unknown. */
  @Nullable public final String schemeType;

  /** Number of {@link SchemeData}s. */
  public final int schemeDataCount;

  /**
   * @param schemeDatas Scheme initialization data for possibly multiple DRM schemes.
   */
  public DrmInitData(List<SchemeData> schemeDatas) {
    this(null, false, schemeDatas.toArray(new SchemeData[0]));
  }

  /**
   * @param schemeType See {@link #schemeType}.
   * @param schemeDatas Scheme initialization data for possibly multiple DRM schemes.
   */
  public DrmInitData(@Nullable String schemeType, List<SchemeData> schemeDatas) {
    this(schemeType, false, schemeDatas.toArray(new SchemeData[0]));
  }

  /**
   * @param schemeDatas Scheme initialization data for possibly multiple DRM schemes.
   */
  public DrmInitData(SchemeData... schemeDatas) {
    this(null, schemeDatas);
  }

  /**
   * @param schemeType See {@link #schemeType}.
   * @param schemeDatas Scheme initialization data for possibly multiple DRM schemes.
   */
  public DrmInitData(@Nullable String schemeType, SchemeData... schemeDatas) {
    this(schemeType, true, schemeDatas);
  }

  private DrmInitData(
      @Nullable String schemeType, boolean cloneSchemeDatas, SchemeData... schemeDatas) {
    this.schemeType = schemeType;
    if (cloneSchemeDatas) {
      schemeDatas = schemeDatas.clone();
    }
    this.schemeDatas = schemeDatas;
    schemeDataCount = schemeDatas.length;
    // Sorting ensures that universal scheme data (i.e. data that applies to all schemes) is matched
    // last. It's also required by the equals and hashcode implementations.
    Arrays.sort(this.schemeDatas, this);
  }

  /* package */ DrmInitData(Parcel in) {
    schemeType = in.readString();
    schemeDatas = Util.castNonNull(in.createTypedArray(SchemeData.CREATOR));
    schemeDataCount = schemeDatas.length;
  }

  /**
   * Retrieves the {@link SchemeData} at a given index.
   *
   * @param index The index of the scheme to return. Must not exceed {@link #schemeDataCount}.
   * @return The {@link SchemeData} at the specified index.
   */
  public SchemeData get(int index) {
    return schemeDatas[index];
  }

  /**
   * Returns a copy with the specified protection scheme type.
   *
   * @param schemeType A protection scheme type. May be null.
   * @return A copy with the specified protection scheme type.
   */
  @CheckResult
  public DrmInitData copyWithSchemeType(@Nullable String schemeType) {
    if (Util.areEqual(this.schemeType, schemeType)) {
      return this;
    }
    return new DrmInitData(schemeType, false, schemeDatas);
  }

  /**
   * Returns an instance containing the {@link #schemeDatas} from both this and {@code other}. The
   * {@link #schemeType} of the instances being merged must either match, or at least one scheme
   * type must be {@code null}.
   *
   * @param drmInitData The instance to merge.
   * @return The merged result.
   */
  public DrmInitData merge(DrmInitData drmInitData) {
    Assertions.checkState(
        schemeType == null
            || drmInitData.schemeType == null
            || TextUtils.equals(schemeType, drmInitData.schemeType));
    String mergedSchemeType = schemeType != null ? this.schemeType : drmInitData.schemeType;
    SchemeData[] mergedSchemeDatas =
        Util.nullSafeArrayConcatenation(schemeDatas, drmInitData.schemeDatas);
    return new DrmInitData(mergedSchemeType, mergedSchemeDatas);
  }

  @Override
  public int hashCode() {
    if (hashCode == 0) {
      int result = (schemeType == null ? 0 : schemeType.hashCode());
      result = 31 * result + Arrays.hashCode(schemeDatas);
      hashCode = result;
    }
    return hashCode;
  }

  @Override
  public boolean equals(@Nullable Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null || getClass() != obj.getClass()) {
      return false;
    }
    DrmInitData other = (DrmInitData) obj;
    return Util.areEqual(schemeType, other.schemeType)
        && Arrays.equals(schemeDatas, other.schemeDatas);
  }

  @Override
  public int compare(SchemeData first, SchemeData second) {
    return C.UUID_NIL.equals(first.uuid)
        ? (C.UUID_NIL.equals(second.uuid) ? 0 : 1)
        : first.uuid.compareTo(second.uuid);
  }

  // Parcelable implementation.

  @Override
  public int describeContents() {
    return 0;
  }

  @Override
  public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(schemeType);
    dest.writeTypedArray(schemeDatas, 0);
  }

  public static final Parcelable.Creator<DrmInitData> CREATOR =
      new Parcelable.Creator<DrmInitData>() {

        @Override
        public DrmInitData createFromParcel(Parcel in) {
          return new DrmInitData(in);
        }

        @Override
        public DrmInitData[] newArray(int size) {
          return new DrmInitData[size];
        }
      };

  // Internal methods.

  private static boolean containsSchemeDataWithUuid(
      ArrayList<SchemeData> datas, int limit, UUID uuid) {
    for (int i = 0; i < limit; i++) {
      if (datas.get(i).uuid.equals(uuid)) {
        return true;
      }
    }
    return false;
  }

  /** Scheme initialization data. */
  public static final class SchemeData implements Parcelable {

    // Lazily initialized hashcode.
    private int hashCode;

    /**
     * The {@link UUID} of the DRM scheme, or {@link C#UUID_NIL} if the data is universal (i.e.
     * applies to all schemes).
     */
    public final UUID uuid;

    /** The URL of the server to which license requests should be made. May be null if unknown. */
    @Nullable public final String licenseServerUrl;

    /** The mimeType of {@link #data}. */
    public final String mimeType;

    /** The initialization data. May be null for scheme support checks only. */
    @Nullable public final byte[] data;

    /**
     * @param uuid The {@link UUID} of the DRM scheme, or {@link C#UUID_NIL} if the data is
     *     universal (i.e. applies to all schemes).
     * @param mimeType See {@link #mimeType}.
     * @param data See {@link #data}.
     */
    public SchemeData(UUID uuid, String mimeType, @Nullable byte[] data) {
      this(uuid, /* licenseServerUrl= */ null, mimeType, data);
    }

    /**
     * @param uuid The {@link UUID} of the DRM scheme, or {@link C#UUID_NIL} if the data is
     *     universal (i.e. applies to all schemes).
     * @param licenseServerUrl See {@link #licenseServerUrl}.
     * @param mimeType See {@link #mimeType}.
     * @param data See {@link #data}.
     */
    public SchemeData(
        UUID uuid, @Nullable String licenseServerUrl, String mimeType, @Nullable byte[] data) {
      this.uuid = Assertions.checkNotNull(uuid);
      this.licenseServerUrl = licenseServerUrl;
      this.mimeType = MimeTypes.normalizeMimeType(Assertions.checkNotNull(mimeType));
      this.data = data;
    }

    /* package */ SchemeData(Parcel in) {
      uuid = new UUID(in.readLong(), in.readLong());
      licenseServerUrl = in.readString();
      mimeType = Util.castNonNull(in.readString());
      data = in.createByteArray();
    }

    /**
     * Returns whether this initialization data applies to the specified scheme.
     *
     * @param schemeUuid The scheme {@link UUID}.
     * @return Whether this initialization data applies to the specified scheme.
     */
    public boolean matches(UUID schemeUuid) {
      return C.UUID_NIL.equals(uuid) || schemeUuid.equals(uuid);
    }

    /**
     * Returns whether this {@link SchemeData} can be used to replace {@code other}.
     *
     * @param other A {@link SchemeData}.
     * @return Whether this {@link SchemeData} can be used to replace {@code other}.
     */
    public boolean canReplace(SchemeData other) {
      return hasData() && !other.hasData() && matches(other.uuid);
    }

    /** Returns whether {@link #data} is non-null. */
    public boolean hasData() {
      return data != null;
    }

    /**
     * Returns a copy of this instance with the specified data.
     *
     * @param data The data to include in the copy.
     * @return The new instance.
     */
    @CheckResult
    public SchemeData copyWithData(@Nullable byte[] data) {
      return new SchemeData(uuid, licenseServerUrl, mimeType, data);
    }

    @Override
    public boolean equals(@Nullable Object obj) {
      if (!(obj instanceof SchemeData)) {
        return false;
      }
      if (obj == this) {
        return true;
      }
      SchemeData other = (SchemeData) obj;
      return Util.areEqual(licenseServerUrl, other.licenseServerUrl)
          && Util.areEqual(mimeType, other.mimeType)
          && Util.areEqual(uuid, other.uuid)
          && Arrays.equals(data, other.data);
    }

    @Override
    public int hashCode() {
      if (hashCode == 0) {
        int result = uuid.hashCode();
        result = 31 * result + (licenseServerUrl == null ? 0 : licenseServerUrl.hashCode());
        result = 31 * result + mimeType.hashCode();
        result = 31 * result + Arrays.hashCode(data);
        hashCode = result;
      }
      return hashCode;
    }

    // Parcelable implementation.

    @Override
    public int describeContents() {
      return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
      dest.writeLong(uuid.getMostSignificantBits());
      dest.writeLong(uuid.getLeastSignificantBits());
      dest.writeString(licenseServerUrl);
      dest.writeString(mimeType);
      dest.writeByteArray(data);
    }

    public static final Parcelable.Creator<SchemeData> CREATOR =
        new Parcelable.Creator<SchemeData>() {

          @Override
          public SchemeData createFromParcel(Parcel in) {
            return new SchemeData(in);
          }

          @Override
          public SchemeData[] newArray(int size) {
            return new SchemeData[size];
          }
        };
  }
}