diff options
| author | 2024-04-17 17:33:03 +0000 | |
|---|---|---|
| committer | 2024-04-17 17:33:03 +0000 | |
| commit | d0d8f0aebe9fcfe0dc1f099c0c3f6ae105d0afd3 (patch) | |
| tree | ff73ff4af6f84fc3dd51c5857f69805e15d55571 | |
| parent | 68402941367b488f21562a3e6af55822a8d0b09a (diff) | |
| parent | 00c8254cb5409ed220a393737f534f8355ab7232 (diff) | |
Merge "Make MediaDrm device-aware" into main
| -rw-r--r-- | media/java/android/media/MediaDrm.java | 17 | ||||
| -rw-r--r-- | media/jni/Android.bp | 2 | ||||
| -rw-r--r-- | media/jni/android_media_MediaDrm.cpp | 43 | ||||
| -rw-r--r-- | media/jni/android_media_MediaDrm.h | 2 |
4 files changed, 64 insertions, 0 deletions
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java index 5331046dd0e3..6593533a843a 100644 --- a/media/java/android/media/MediaDrm.java +++ b/media/java/android/media/MediaDrm.java @@ -205,6 +205,10 @@ public final class MediaDrm implements AutoCloseable { * media container format specified by mimeType at the requested * security level. * + * Calling this method while the application is running on the physical Android device or a + * {@link android.companion.virtual.VirtualDevice} may lead to different results, based on + * the different DRM capabilities of the devices. + * * @param uuid The UUID of the crypto scheme. * @param mimeType The MIME type of the media container, e.g. "video/mp4" * or "video/webm" @@ -1400,6 +1404,10 @@ public final class MediaDrm implements AutoCloseable { * Open a new session with the MediaDrm object. A session ID is returned. * By default, sessions are opened at the native security level of the device. * + * If the application is currently running on a {@link android.companion.virtual.VirtualDevice} + * the security level will be adjusted accordingly to the maximum supported level for the + * display. + * * @throws NotProvisionedException if provisioning is needed * @throws ResourceBusyException if required resources are in use */ @@ -1422,6 +1430,10 @@ public final class MediaDrm implements AutoCloseable { * can be queried using {@link #getSecurityLevel}. A session * ID is returned. * + * If the application is currently running on a {@link android.companion.virtual.VirtualDevice} + * the security level will be adjusted accordingly to the maximum supported level for the + * display. + * * @param level the new security level * @throws NotProvisionedException if provisioning is needed * @throws ResourceBusyException if required resources are in use @@ -2180,6 +2192,11 @@ public final class MediaDrm implements AutoCloseable { * Returns a value that may be passed as a parameter to {@link #openSession(int)} * requesting that the session be opened at the maximum security level of * the device. + * + * This security level is only valid for the application running on the physical Android + * device (e.g. {@link android.content.Context#DEVICE_ID_DEFAULT}). While running on a + * {@link android.companion.virtual.VirtualDevice} the maximum supported security level + * might be different. */ public static final int getMaxSecurityLevel() { return SECURITY_LEVEL_MAX; diff --git a/media/jni/Android.bp b/media/jni/Android.bp index 94fce797f5d6..8609c4df1298 100644 --- a/media/jni/Android.bp +++ b/media/jni/Android.bp @@ -82,6 +82,7 @@ cc_library_shared { "libhidlbase", "libsonivox", "server_configurable_flags", + "android.companion.virtual.virtualdevice_aidl-cpp", "android.hardware.cas@1.0", "android.hardware.cas.native@1.0", "android.hardware.drm@1.3", @@ -100,6 +101,7 @@ cc_library_shared { static_libs: [ "libgrallocusage", "libmedia_midiiowrapper", + "android.companion.virtualdevice.flags-aconfig-cc", "android.media.playback.flags-aconfig-cc", ], diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp index 1c25080939da..48cd53dc44d7 100644 --- a/media/jni/android_media_MediaDrm.cpp +++ b/media/jni/android_media_MediaDrm.cpp @@ -27,6 +27,8 @@ #include "jni.h" #include <nativehelper/JNIHelp.h> +#include <android_companion_virtualdevice_flags.h> +#include <android/companion/virtualnative/IVirtualDeviceManagerNative.h> #include <android/hardware/drm/1.3/IDrmFactory.h> #include <binder/Parcel.h> #include <binder/PersistableBundle.h> @@ -41,8 +43,10 @@ #include <map> #include <string> +using ::android::companion::virtualnative::IVirtualDeviceManagerNative; using ::android::os::PersistableBundle; namespace drm = ::android::hardware::drm; +namespace virtualdevice_flags = android::companion::virtualdevice::flags; namespace android { @@ -1045,6 +1049,26 @@ DrmPlugin::SecurityLevel jintToSecurityLevel(jint jlevel) { return level; } +std::vector<int> getVirtualDeviceIds() { + if (!virtualdevice_flags::device_aware_drm()) { + ALOGW("Device-aware DRM flag disabled."); + return std::vector<int>(); + } + + sp<IBinder> binder = + defaultServiceManager()->checkService(String16("virtualdevice_native")); + if (binder != nullptr) { + auto vdm = interface_cast<IVirtualDeviceManagerNative>(binder); + std::vector<int> deviceIds; + const uid_t uid = IPCThreadState::self()->getCallingUid(); + vdm->getDeviceIdsForUid(uid, &deviceIds); + return deviceIds; + } else { + ALOGW("Cannot get virtualdevice_native service"); + return std::vector<int>(); + } +} + static jbyteArray android_media_MediaDrm_getSupportedCryptoSchemesNative(JNIEnv *env) { sp<IDrm> drm = android::DrmUtils::MakeDrm(); if (drm == NULL) return env->NewByteArray(0); @@ -1081,6 +1105,15 @@ static jboolean android_media_MediaDrm_isCryptoSchemeSupportedNative( } DrmPlugin::SecurityLevel securityLevel = jintToSecurityLevel(jSecurityLevel); + if (getVirtualDeviceIds().size() > 0) { + // Cap security level at max SECURITY_LEVEL_SW_SECURE_CRYPTO because at + // higher security levels decode output cannot be captured and + // streamed to virtual devices rendered on virtual displays. + if (securityLevel > DrmPlugin::kSecurityLevelSwSecureCrypto) { + return false; + } + } + bool isSupported; status_t err = JDrm::IsCryptoSchemeSupported(uuid.array(), mimeType, securityLevel, &isSupported); @@ -1106,6 +1139,16 @@ static jbyteArray android_media_MediaDrm_openSession( return NULL; } + if (getVirtualDeviceIds().size() > 0) { + // Cap security level at max SECURITY_LEVEL_SW_SECURE_CRYPTO because at + // higher security levels decode output cannot be captured and + // streamed to virtual devices rendered on virtual displays. + if (level == DrmPlugin::kSecurityLevelMax || + level > DrmPlugin::kSecurityLevelSwSecureCrypto) { + level = DrmPlugin::kSecurityLevelSwSecureCrypto; + } + } + DrmStatus err = drm->openSession(level, sessionId); if (throwExceptionAsNecessary(env, drm, err, "Failed to open session")) { diff --git a/media/jni/android_media_MediaDrm.h b/media/jni/android_media_MediaDrm.h index a64e3f2a7cf0..36cba2dc3c7e 100644 --- a/media/jni/android_media_MediaDrm.h +++ b/media/jni/android_media_MediaDrm.h @@ -19,6 +19,8 @@ #include "jni.h" +#include <binder/IPCThreadState.h> +#include <binder/IServiceManager.h> #include <media/stagefright/foundation/ABase.h> #include <mediadrm/IDrm.h> #include <mediadrm/IDrmClient.h> |