Add new APIs to ExoMediaDrm
Changes --- - Added `removeOfflineLicense(byte[])` and `getOfflineLicenseKeySetIds` and consumed them in their implementations Background --- - These APIs will help in addressing an increasing amount of `java.lang.IllegalArgumentException: Failed to restore keys: BAD_VALUE` which is our top playback error in our app - Based on our discussion with Widevine team and [this exoplayer issue](https://github.com/google/ExoPlayer/issues/11202#issuecomment-1708792594) - TL;DR: The failure occurs on startup if the user has 200+ offline licenses, we would like to add the functionality to remove offline licenses **Note: Why we want these APIs in ExoMediaDrm and not in OfflineLicenseHelper** - As per the issue above, we would like to access these 2 public APIs in MediaDrm that don’t exist in `OfflineLicenseHelper` or `ExoMediaDrm` - APIs interested in: - [MediaDrm#removeOfflineLicense()](https://developer.android.com/reference/android/media/MediaDrm#removeOfflineLicense(byte%5B%5D)): To remove offline license - [MediaDrm#getOfflineLicenseKeySetIds()](https://developer.android.com/reference/android/media/MediaDrm#getOfflineLicenseKeySetIds()): To see number of offline licenses on startup - We use `OfflineLicenseHelper` to download license for L1 and we don't interact with `ExoMediaDrm` directly. But for the alternate Widevine integration, we directly depend on `ExoMediaDrm` APIs to override and call CDM Native APIs. - We would like to have the functionality of removing offline licenses for both integration which would need access to above APIs in `ExoMediaDrm`. Links --- - https://github.com/androidx/media/issues/659
This commit is contained in:
parent
ffd7bb5639
commit
aba15b6952
@ -24,6 +24,7 @@ import androidx.media3.common.DrmInitData;
|
|||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
import androidx.media3.decoder.CryptoConfig;
|
import androidx.media3.decoder.CryptoConfig;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -156,4 +157,15 @@ public final class DummyExoMediaDrm implements ExoMediaDrm {
|
|||||||
public @C.CryptoType int getCryptoType() {
|
public @C.CryptoType int getCryptoType() {
|
||||||
return C.CRYPTO_TYPE_UNSUPPORTED;
|
return C.CRYPTO_TYPE_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeOfflineLicense(byte[] keySetId) {
|
||||||
|
// Should not be invoked. No session should exist.
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<byte[]> getOfflineLicenseKeySetIds() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -583,4 +583,19 @@ public interface ExoMediaDrm {
|
|||||||
*/
|
*/
|
||||||
@C.CryptoType
|
@C.CryptoType
|
||||||
int getCryptoType();
|
int getCryptoType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes an offline license.
|
||||||
|
* This method is generally not needed, and should only be used if the preferred approach of passing {@link MediaDrm#KEY_TYPE_RELEASE} to {@link #getKeyRequest} is not possible.
|
||||||
|
*
|
||||||
|
* See {@link MediaDrm#removeOfflineLicense(byte[])} for more details.
|
||||||
|
*/
|
||||||
|
void removeOfflineLicense(byte[] keySetId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a list of the keySetIds for all offline licenses.
|
||||||
|
*
|
||||||
|
* See {@link MediaDrm#getOfflineLicenseKeySetIds()} for more details.
|
||||||
|
*/
|
||||||
|
List<byte[]> getOfflineLicenseKeySetIds();
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import android.media.MediaDrmException;
|
|||||||
import android.media.NotProvisionedException;
|
import android.media.NotProvisionedException;
|
||||||
import android.media.UnsupportedSchemeException;
|
import android.media.UnsupportedSchemeException;
|
||||||
import android.media.metrics.LogSessionId;
|
import android.media.metrics.LogSessionId;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.PersistableBundle;
|
import android.os.PersistableBundle;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import androidx.annotation.DoNotInline;
|
import androidx.annotation.DoNotInline;
|
||||||
@ -46,6 +47,7 @@ import com.google.common.base.Charsets;
|
|||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -380,6 +382,26 @@ public final class FrameworkMediaDrm implements ExoMediaDrm {
|
|||||||
return C.CRYPTO_TYPE_FRAMEWORK;
|
return C.CRYPTO_TYPE_FRAMEWORK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@RequiresApi(Build.VERSION_CODES.Q)
|
||||||
|
public void removeOfflineLicense(byte[] keySetId) {
|
||||||
|
if (Util.SDK_INT < Build.VERSION_CODES.Q) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
mediaDrm.removeOfflineLicense(keySetId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@RequiresApi(Build.VERSION_CODES.Q)
|
||||||
|
public List<byte[]> getOfflineLicenseKeySetIds() {
|
||||||
|
if (Util.SDK_INT < Build.VERSION_CODES.Q) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return mediaDrm.getOfflineLicenseKeySetIds();
|
||||||
|
}
|
||||||
|
|
||||||
private static SchemeData getSchemeData(UUID uuid, List<SchemeData> schemeDatas) {
|
private static SchemeData getSchemeData(UUID uuid, List<SchemeData> schemeDatas) {
|
||||||
if (!C.WIDEVINE_UUID.equals(uuid)) {
|
if (!C.WIDEVINE_UUID.equals(uuid)) {
|
||||||
// For non-Widevine CDMs always use the first scheme data.
|
// For non-Widevine CDMs always use the first scheme data.
|
||||||
|
@ -43,6 +43,7 @@ import com.google.common.primitives.Bytes;
|
|||||||
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -413,6 +414,16 @@ public final class FakeExoMediaDrm implements ExoMediaDrm {
|
|||||||
return FakeCryptoConfig.TYPE;
|
return FakeCryptoConfig.TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeOfflineLicense(byte[] keySetId) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<byte[]> getOfflineLicenseKeySetIds() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
// Methods to facilitate testing
|
// Methods to facilitate testing
|
||||||
|
|
||||||
public int getReferenceCount() {
|
public int getReferenceCount() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user