Skip to content

Commit

Permalink
Check WV version before relying on MediaDrm.requiresSecureDecoder
Browse files Browse the repository at this point in the history
This method was added in API 31 (S) but it's non-functional
(incorrectly, silently, returns `false`) on the Widevine plugin version
(`16.0`) from R (API 30), which some devices up to at least API 34 are
still using.

This results in ExoPlayer incorrectly selecting an insecure decoder for
L1 secure content, and subsequently calling
`MediaCodec.queueInputBuffer` instead of `queueSecureInputBuffer`,
which is not supported and generates the following error:
> Operation not supported in this configuration: ERROR_DRM_CANNOT_HANDLE

Issue: #1603

#cherrypick

PiperOrigin-RevId: 662852176
  • Loading branch information
icbaker authored and copybara-github committed Aug 14, 2024
1 parent e7f037b commit ca455ee
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
6 changes: 6 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@
read from a `FileDescriptor`
([#3757](https://github.com/google/ExoPlayer/issues/3757)).
* DRM:
* Fix `android.media.MediaCodec$CryptoException: Operation not supported
in this configuration: ERROR_DRM_CANNOT_HANDLE` error on API 31+ devices
playing L1 Widevine content. This error is caused by an incomplete
implementation of the framework
[`MediaDrm.requiresSecureDecoder`](https://developer.android.com/reference/android/media/MediaDrm#requiresSecureDecoder\(java.lang.String\))
method ([#1603](https://github.com/google/ExoPlayer/issues/1603)).
* Effect:
* Add `DefaultVideoFrameProcessor` workaround for minor `SurfaceTexture`
scaling. `SurfaceTexture` may include a small scaling that cuts off a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ public Map<String, String> queryKeyStatus(byte[] sessionId) {
@Override
public boolean requiresSecureDecoder(byte[] sessionId, String mimeType) {
boolean result;
if (Util.SDK_INT >= 31) {
if (Util.SDK_INT >= 31 && isMediaDrmRequiresSecureDecoderImplemented()) {
result = Api31.requiresSecureDecoder(mediaDrm, mimeType);
} else {
MediaCrypto mediaCrypto = null;
Expand Down Expand Up @@ -398,6 +398,26 @@ public FrameworkCryptoConfig createCryptoConfig(byte[] sessionId) throws MediaCr
return C.CRYPTO_TYPE_FRAMEWORK;
}

/**
* {@link MediaDrm#requiresSecureDecoder} is nominally available from API 31, but it's only
* functional for Widevine if the plugin version is greater than 16.0. See b/352419654#comment63.
*/
@RequiresApi(31)
private boolean isMediaDrmRequiresSecureDecoderImplemented() {
// TODO: b/359768062 - Add an SDK_INT guard clause once WV 16.0 is not permitted on any device.
if (uuid.equals(C.WIDEVINE_UUID)) {
String pluginVersion = getPropertyString(MediaDrm.PROPERTY_VERSION);
return !pluginVersion.startsWith("v5.")
&& !pluginVersion.startsWith("14.")
&& !pluginVersion.startsWith("15.")
&& !pluginVersion.startsWith("16.0");
} else {
// Assume that ClearKey plugin always supports this method, and no non-Google plugin does. See
// b/352419654#comment71.
return uuid.equals(C.CLEARKEY_UUID);
}
}

private static SchemeData getSchemeData(UUID uuid, List<SchemeData> schemeDatas) {
if (!C.WIDEVINE_UUID.equals(uuid)) {
// For non-Widevine CDMs always use the first scheme data.
Expand Down

0 comments on commit ca455ee

Please sign in to comment.