diff options
Diffstat (limited to '')
-rw-r--r-- | mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/drm/ExoMediaDrm.java | 342 |
1 files changed, 342 insertions, 0 deletions
diff --git a/mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/drm/ExoMediaDrm.java b/mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/drm/ExoMediaDrm.java new file mode 100644 index 0000000000..1e851a7c0b --- /dev/null +++ b/mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/drm/ExoMediaDrm.java @@ -0,0 +1,342 @@ +/* + * 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 org.mozilla.thirdparty.com.google.android.exoplayer2.drm; + +import android.media.DeniedByServerException; +import android.media.MediaCryptoException; +import android.media.MediaDrm; +import android.media.MediaDrmException; +import android.media.NotProvisionedException; +import android.os.Handler; +import android.os.PersistableBundle; +import androidx.annotation.Nullable; +import org.mozilla.thirdparty.com.google.android.exoplayer2.drm.DrmInitData.SchemeData; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +/** + * Used to obtain keys for decrypting protected media streams. See {@link android.media.MediaDrm}. + * + * <h3>Reference counting</h3> + * + * <p>Access to an instance is managed by reference counting, where {@link #acquire()} increments + * the reference count and {@link #release()} decrements it. When the reference count drops to 0 + * underlying resources are released, and the instance cannot be re-used. + * + * <p>Each new instance has an initial reference count of 1. Hence application code that creates a + * new instance does not normally need to call {@link #acquire()}, and must call {@link #release()} + * when the instance is no longer required. + */ +public interface ExoMediaDrm<T extends ExoMediaCrypto> { + + /** {@link ExoMediaDrm} instances provider. */ + interface Provider<T extends ExoMediaCrypto> { + + /** + * Returns an {@link ExoMediaDrm} instance with an incremented reference count. When the caller + * no longer needs to use the instance, it must call {@link ExoMediaDrm#release()} to decrement + * the reference count. + */ + ExoMediaDrm<T> acquireExoMediaDrm(UUID uuid); + } + + /** + * Provides an {@link ExoMediaDrm} instance owned by the app. + * + * <p>Note that when using this provider the app will have instantiated the {@link ExoMediaDrm} + * instance, and remains responsible for calling {@link ExoMediaDrm#release()} on the instance + * when it's no longer being used. + */ + final class AppManagedProvider<T extends ExoMediaCrypto> implements Provider<T> { + + private final ExoMediaDrm<T> exoMediaDrm; + + /** Creates an instance that provides the given {@link ExoMediaDrm}. */ + public AppManagedProvider(ExoMediaDrm<T> exoMediaDrm) { + this.exoMediaDrm = exoMediaDrm; + } + + @Override + public ExoMediaDrm<T> acquireExoMediaDrm(UUID uuid) { + exoMediaDrm.acquire(); + return exoMediaDrm; + } + } + + /** @see MediaDrm#EVENT_KEY_REQUIRED */ + @SuppressWarnings("InlinedApi") + int EVENT_KEY_REQUIRED = MediaDrm.EVENT_KEY_REQUIRED; + /** + * @see MediaDrm#EVENT_KEY_EXPIRED + */ + @SuppressWarnings("InlinedApi") + int EVENT_KEY_EXPIRED = MediaDrm.EVENT_KEY_EXPIRED; + /** + * @see MediaDrm#EVENT_PROVISION_REQUIRED + */ + @SuppressWarnings("InlinedApi") + int EVENT_PROVISION_REQUIRED = MediaDrm.EVENT_PROVISION_REQUIRED; + + /** + * @see MediaDrm#KEY_TYPE_STREAMING + */ + @SuppressWarnings("InlinedApi") + int KEY_TYPE_STREAMING = MediaDrm.KEY_TYPE_STREAMING; + /** + * @see MediaDrm#KEY_TYPE_OFFLINE + */ + @SuppressWarnings("InlinedApi") + int KEY_TYPE_OFFLINE = MediaDrm.KEY_TYPE_OFFLINE; + /** + * @see MediaDrm#KEY_TYPE_RELEASE + */ + @SuppressWarnings("InlinedApi") + int KEY_TYPE_RELEASE = MediaDrm.KEY_TYPE_RELEASE; + + /** + * @see android.media.MediaDrm.OnEventListener + */ + interface OnEventListener<T extends ExoMediaCrypto> { + /** + * Called when an event occurs that requires the app to be notified + * + * @param mediaDrm The {@link ExoMediaDrm} object on which the event occurred. + * @param sessionId The DRM session ID on which the event occurred. + * @param event Indicates the event type. + * @param extra A secondary error code. + * @param data Optional byte array of data that may be associated with the event. + */ + void onEvent( + ExoMediaDrm<? extends T> mediaDrm, + @Nullable byte[] sessionId, + int event, + int extra, + @Nullable byte[] data); + } + + /** + * @see android.media.MediaDrm.OnKeyStatusChangeListener + */ + interface OnKeyStatusChangeListener<T extends ExoMediaCrypto> { + /** + * Called when the keys in a session change status, such as when the license is renewed or + * expires. + * + * @param mediaDrm The {@link ExoMediaDrm} object on which the event occurred. + * @param sessionId The DRM session ID on which the event occurred. + * @param exoKeyInformation A list of {@link KeyStatus} that contains key ID and status. + * @param hasNewUsableKey Whether a new key became usable. + */ + void onKeyStatusChange( + ExoMediaDrm<? extends T> mediaDrm, + byte[] sessionId, + List<KeyStatus> exoKeyInformation, + boolean hasNewUsableKey); + } + + /** @see android.media.MediaDrm.KeyStatus */ + final class KeyStatus { + + private final int statusCode; + private final byte[] keyId; + + public KeyStatus(int statusCode, byte[] keyId) { + this.statusCode = statusCode; + this.keyId = keyId; + } + + public int getStatusCode() { + return statusCode; + } + + public byte[] getKeyId() { + return keyId; + } + + } + + /** @see android.media.MediaDrm.KeyRequest */ + final class KeyRequest { + + private final byte[] data; + private final String licenseServerUrl; + + public KeyRequest(byte[] data, String licenseServerUrl) { + this.data = data; + this.licenseServerUrl = licenseServerUrl; + } + + public byte[] getData() { + return data; + } + + public String getLicenseServerUrl() { + return licenseServerUrl; + } + + } + + /** @see android.media.MediaDrm.ProvisionRequest */ + final class ProvisionRequest { + + private final byte[] data; + private final String defaultUrl; + + public ProvisionRequest(byte[] data, String defaultUrl) { + this.data = data; + this.defaultUrl = defaultUrl; + } + + public byte[] getData() { + return data; + } + + public String getDefaultUrl() { + return defaultUrl; + } + + } + + /** + * @see MediaDrm#setOnEventListener(MediaDrm.OnEventListener) + */ + void setOnEventListener(OnEventListener<? super T> listener); + + /** + * @see MediaDrm#setOnKeyStatusChangeListener(MediaDrm.OnKeyStatusChangeListener, Handler) + */ + void setOnKeyStatusChangeListener(OnKeyStatusChangeListener<? super T> listener); + + /** + * @see MediaDrm#openSession() + */ + byte[] openSession() throws MediaDrmException; + + /** + * @see MediaDrm#closeSession(byte[]) + */ + void closeSession(byte[] sessionId); + + /** + * Generates a key request. + * + * @param scope If {@code keyType} is {@link #KEY_TYPE_STREAMING} or {@link #KEY_TYPE_OFFLINE}, + * the session id that the keys will be provided to. If {@code keyType} is {@link + * #KEY_TYPE_RELEASE}, the keySetId of the keys to release. + * @param schemeDatas If key type is {@link #KEY_TYPE_STREAMING} or {@link #KEY_TYPE_OFFLINE}, a + * list of {@link SchemeData} instances extracted from the media. Null otherwise. + * @param keyType The type of the request. Either {@link #KEY_TYPE_STREAMING} to acquire keys for + * streaming, {@link #KEY_TYPE_OFFLINE} to acquire keys for offline usage, or {@link + * #KEY_TYPE_RELEASE} to release acquired keys. Releasing keys invalidates them for all + * sessions. + * @param optionalParameters Are included in the key request message to allow a client application + * to provide additional message parameters to the server. This may be {@code null} if no + * additional parameters are to be sent. + * @return The generated key request. + * @see MediaDrm#getKeyRequest(byte[], byte[], String, int, HashMap) + */ + KeyRequest getKeyRequest( + byte[] scope, + @Nullable List<SchemeData> schemeDatas, + int keyType, + @Nullable HashMap<String, String> optionalParameters) + throws NotProvisionedException; + + /** @see MediaDrm#provideKeyResponse(byte[], byte[]) */ + @Nullable + byte[] provideKeyResponse(byte[] scope, byte[] response) + throws NotProvisionedException, DeniedByServerException; + + /** + * @see MediaDrm#getProvisionRequest() + */ + ProvisionRequest getProvisionRequest(); + + /** + * @see MediaDrm#provideProvisionResponse(byte[]) + */ + void provideProvisionResponse(byte[] response) throws DeniedByServerException; + + /** + * @see MediaDrm#queryKeyStatus(byte[]) + */ + Map<String, String> queryKeyStatus(byte[] sessionId); + + /** + * Increments the reference count. When the caller no longer needs to use the instance, it must + * call {@link #release()} to decrement the reference count. + * + * <p>A new instance will have an initial reference count of 1, and therefore it is not normally + * necessary for application code to call this method. + */ + void acquire(); + + /** + * Decrements the reference count. If the reference count drops to 0 underlying resources are + * released, and the instance cannot be re-used. + */ + void release(); + + /** + * @see MediaDrm#restoreKeys(byte[], byte[]) + */ + void restoreKeys(byte[] sessionId, byte[] keySetId); + + /** + * Returns drm metrics. May be null if unavailable. + * + * @see MediaDrm#getMetrics() + */ + @Nullable + PersistableBundle getMetrics(); + + /** + * @see MediaDrm#getPropertyString(String) + */ + String getPropertyString(String propertyName); + + /** + * @see MediaDrm#getPropertyByteArray(String) + */ + byte[] getPropertyByteArray(String propertyName); + + /** + * @see MediaDrm#setPropertyString(String, String) + */ + void setPropertyString(String propertyName, String value); + + /** + * @see MediaDrm#setPropertyByteArray(String, byte[]) + */ + void setPropertyByteArray(String propertyName, byte[] value); + + /** + * @see android.media.MediaCrypto#MediaCrypto(UUID, byte[]) + * @param sessionId The DRM session ID. + * @return An object extends {@link ExoMediaCrypto}, using opaque crypto scheme specific data. + * @throws MediaCryptoException If the instance can't be created. + */ + T createMediaCrypto(byte[] sessionId) throws MediaCryptoException; + + /** + * Returns the {@link ExoMediaCrypto} type created by {@link #createMediaCrypto(byte[])}, or null + * if this instance cannot create any {@link ExoMediaCrypto} instances. + */ + @Nullable + Class<T> getExoMediaCryptoType(); +} |