From e9786259ace64e053eb496d838519da7dd2af082 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Tue, 19 Mar 2019 23:06:39 -0700 Subject: [PATCH] MediaPlayer2 DRM: API improvements * Document how to build valid DrmPreparationInfo * Add getters for DrmPreparationInfo * Make DrmEventCallback an abstract class * Document set/clearDrmEventCallback are synchronous Bug: 128548364 Test: build Change-Id: Iecc2a8bcd410ea729ac9fd4c2b3f1428fc4b5e7d --- api/current.txt | 15 ++- .../apex/java/android/media/MediaPlayer2.java | 104 ++++++++++++++---- 2 files changed, 90 insertions(+), 29 deletions(-) diff --git a/api/current.txt b/api/current.txt index 3e7d6268896a0..9f14ec59d2896 100644 --- a/api/current.txt +++ b/api/current.txt @@ -25696,11 +25696,11 @@ package android.media { field public static final int SEEK_PREVIOUS_SYNC = 0; // 0x0 } - public static class MediaPlayer2.DrmEventCallback { + public abstract static class MediaPlayer2.DrmEventCallback { ctor public MediaPlayer2.DrmEventCallback(); method public void onDrmConfig(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaDrm); - method @Nullable public android.media.MediaPlayer2.DrmPreparationInfo onDrmInfo(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaPlayer2.DrmInfo); - method @NonNull public byte[] onDrmKeyRequest(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaDrm.KeyRequest); + method @Nullable public abstract android.media.MediaPlayer2.DrmPreparationInfo onDrmInfo(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaPlayer2.DrmInfo); + method @NonNull public abstract byte[] onDrmKeyRequest(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, @NonNull android.media.MediaDrm.KeyRequest); method public void onDrmPrepared(@NonNull android.media.MediaPlayer2, @NonNull android.media.DataSourceDesc, int, @Nullable byte[]); } @@ -25710,17 +25710,22 @@ package android.media { } public static final class MediaPlayer2.DrmPreparationInfo { + method @Nullable public byte[] getInitData(); + method @Nullable public byte[] getKeySetId(); + method public int getKeyType(); + method @Nullable public String getMimeType(); + method @Nullable public java.util.Map getOptionalParameters(); + method @NonNull public java.util.UUID getUuid(); } public static final class MediaPlayer2.DrmPreparationInfo.Builder { - ctor public MediaPlayer2.DrmPreparationInfo.Builder(); + ctor public MediaPlayer2.DrmPreparationInfo.Builder(@NonNull java.util.UUID); method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo build(); method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setInitData(@Nullable byte[]); method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setKeySetId(@Nullable byte[]); method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setKeyType(int); method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setMimeType(@Nullable String); method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setOptionalParameters(@Nullable java.util.Map); - method @NonNull public android.media.MediaPlayer2.DrmPreparationInfo.Builder setUuid(@NonNull java.util.UUID); } public static class MediaPlayer2.EventCallback { diff --git a/media/apex/java/android/media/MediaPlayer2.java b/media/apex/java/android/media/MediaPlayer2.java index fbe184bf144f2..47fa58499d0bc 100644 --- a/media/apex/java/android/media/MediaPlayer2.java +++ b/media/apex/java/android/media/MediaPlayer2.java @@ -3446,10 +3446,18 @@ public class MediaPlayer2 implements AutoCloseable /** * Mutable builder to create a {@link MediaPlayer2.DrmPreparationInfo} object. + * + * {@link Builder#Builder(UUID) UUID} must not be null; {@link #setKeyType keyType} + * must be one of {@link MediaDrm#KEY_TYPE_STREAMING} or {@link MediaDrm#KEY_TYPE_OFFLINE}. + *

+ * When {@link #setKeyType keyType} is {@link MediaDrm#KEY_TYPE_STREAMING}, + * {@link #setInitData(byte[]) initData} and {@link #setMimeType(String) mimeType} + * must not be null; When {@link #setKeyType keyType} is {@link MediaDrm#KEY_TYPE_OFFLINE}, + * {@link #setKeySetId(byte[]) keySetId} must not be null. */ public static final class Builder { - private UUID mUUID; + private final UUID mUUID; private byte[] mKeySetId; private byte[] mInitData; private String mMimeType; @@ -3457,15 +3465,11 @@ public class MediaPlayer2 implements AutoCloseable private Map mOptionalParameters; /** - * Set UUID of the crypto scheme selected to decrypt content. An UUID can be retrieved - * from the source listening to {@link MediaPlayer2.DrmEventCallback#onDrmInfo}. - * - * @param uuid of selected crypto scheme - * @return this + * @param uuid UUID of the crypto scheme selected to decrypt content. An UUID can be + * retrieved from the source listening to {@link DrmEventCallback#onDrmInfo}. */ - public @NonNull Builder setUuid(@NonNull UUID uuid) { + public Builder(@NonNull UUID uuid) { this.mUUID = uuid; - return this; } /** @@ -3538,12 +3542,16 @@ public class MediaPlayer2 implements AutoCloseable } /** - * @return an immutable {@link MediaPlayer2.DrmPreparationInfo} representing the - * settings of this builder + * @return an immutable {@link DrmPreparationInfo} based on settings of this builder */ - public @NonNull MediaPlayer2.DrmPreparationInfo build() { - return new MediaPlayer2.DrmPreparationInfo(mUUID, mKeySetId, mInitData, mMimeType, - mKeyType, mOptionalParameters); + @NonNull + public DrmPreparationInfo build() { + final DrmPreparationInfo info = new DrmPreparationInfo(mUUID, mKeySetId, mInitData, + mMimeType, mKeyType, mOptionalParameters); + if (!info.isValid()) { + throw new IllegalArgumentException("invalid DrmPreparationInfo"); + } + return info; } } @@ -3579,13 +3587,61 @@ public class MediaPlayer2 implements AutoCloseable } return false; } + + /** + * @return UUID of the crypto scheme selected to decrypt content. + */ + @NonNull + public UUID getUuid() { + return mUUID; + } + + /** + * @return identifier of the persisted offline key. + */ + @Nullable + public byte[] getKeySetId() { + return mKeySetId; + } + + /** + * @return container-specific DRM initialization data. + */ + @Nullable + public byte[] getInitData() { + return mInitData; + } + + /** + * @return mime type of the content + */ + @Nullable + public String getMimeType() { + return mMimeType; + } + + /** + * @return type of the key request. + */ + @MediaPlayer2.MediaDrmKeyType + public int getKeyType() { + return mKeyType; + } + + /** + * @return optional parameters to be included in the {@link MediaDrm.KeyRequest}. + */ + @Nullable + public Map getOptionalParameters() { + return mOptionalParameters; + } } /** * Interface definition for callbacks to be invoked when the player has the corresponding * DRM events. */ - public static class DrmEventCallback { + public static abstract class DrmEventCallback { /** * Called to indicate DRM info is available. Return a {@link DrmPreparationInfo} object that @@ -3598,10 +3654,9 @@ public class MediaPlayer2 implements AutoCloseable * @return a {@link DrmPreparationInfo} object to initialize DRM playback, or null to skip * DRM initialization */ - public @Nullable DrmPreparationInfo onDrmInfo(@NonNull MediaPlayer2 mp, - @NonNull DataSourceDesc dsd, @NonNull DrmInfo drmInfo) { - return null; - } + @Nullable + public abstract DrmPreparationInfo onDrmInfo(@NonNull MediaPlayer2 mp, + @NonNull DataSourceDesc dsd, @NonNull DrmInfo drmInfo); /** * Called to give the app the opportunity to configure DRM before the session is created. @@ -3636,10 +3691,9 @@ public class MediaPlayer2 implements AutoCloseable * throwing an {@link RuntimeException} from this callback would trigger an * {@link EventCallback#onError}. */ - public @NonNull byte[] onDrmKeyRequest(@NonNull MediaPlayer2 mp, - @NonNull DataSourceDesc dsd, @NonNull MediaDrm.KeyRequest request) { - return new byte[0]; - } + @NonNull + public abstract byte[] onDrmKeyRequest(@NonNull MediaPlayer2 mp, + @NonNull DataSourceDesc dsd, @NonNull MediaDrm.KeyRequest request); /** * Called to notify the client that {@code mp} is ready to decrypt DRM protected data source @@ -3664,10 +3718,11 @@ public class MediaPlayer2 implements AutoCloseable /** * Registers the callback to be invoked for various DRM events. * + * This is a synchronous call. + * * @param eventCallback the callback that will be run * @param executor the executor through which the callback should be invoked */ - // This is a synchronous call. public void setDrmEventCallback(@NonNull @CallbackExecutor Executor executor, @NonNull DrmEventCallback eventCallback) { if (eventCallback == null) { @@ -3684,8 +3739,9 @@ public class MediaPlayer2 implements AutoCloseable /** * Clear the {@link DrmEventCallback}. + * + * This is a synchronous call. */ - // This is a synchronous call. public void clearDrmEventCallback() { synchronized (mDrmEventCallbackLock) { mDrmEventCallback = null;