diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 2a96580b1410c..e3504fa349a09 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -2812,7 +2812,13 @@ @hide This is not a third-party API (intended for system apps). --> + + + + remove DRM certificates + + Allows an application to remove DRM certficates. Should never be needed for normal apps. + diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java index 25f10d230eb2e..ca707d87460da 100644 --- a/media/java/android/media/MediaDrm.java +++ b/media/java/android/media/MediaDrm.java @@ -20,6 +20,7 @@ import java.lang.ref.WeakReference; import java.util.UUID; import java.util.HashMap; import java.util.List; +import android.annotation.SystemApi; import android.os.Binder; import android.os.Debug; import android.os.Handler; @@ -520,6 +521,18 @@ public final class MediaDrm { private native Certificate provideProvisionResponseNative(byte[] response) throws DeniedByServerException; + /** + * Remove provisioning from a device. Only system apps may unprovision a + * device. Note that removing provisioning will invalidate any keys saved + * for offline use (KEY_TYPE_OFFLINE), which may render downloaded content + * unplayable until new licenses are acquired. Since provisioning is global + * to the device, license invalidation will apply to all content downloaded + * by any app, so appropriate warnings should be given to the user. + * @hide + */ + @SystemApi + public native void unprovisionDevice(); + /** * A means of enforcing limits on the number of concurrent streams per subscriber * across devices is provided via SecureStop. This is achieved by securely diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp index 5f27b168739ba..c678ac7248e86 100644 --- a/media/jni/android_media_MediaDrm.cpp +++ b/media/jni/android_media_MediaDrm.cpp @@ -966,6 +966,22 @@ static jobject android_media_MediaDrm_provideProvisionResponseNative( return certificateObj; } +static void android_media_MediaDrm_unprovisionDeviceNative( + JNIEnv *env, jobject thiz) { + sp drm = GetDrm(env, thiz); + + if (drm == NULL) { + jniThrowException(env, "java/lang/IllegalStateException", + "MediaDrm obj is null"); + return; + } + + status_t err = drm->unprovisionDevice(); + + throwExceptionAsNecessary(env, err, "Failed to handle provision response"); + return; +} + static jobject android_media_MediaDrm_getSecureStops( JNIEnv *env, jobject thiz) { sp drm = GetDrm(env, thiz); @@ -1362,6 +1378,9 @@ static JNINativeMethod gMethods[] = { { "provideProvisionResponseNative", "([B)Landroid/media/MediaDrm$Certificate;", (void *)android_media_MediaDrm_provideProvisionResponseNative }, + { "unprovisionDevice", "()V", + (void *)android_media_MediaDrm_unprovisionDeviceNative }, + { "getSecureStops", "()Ljava/util/List;", (void *)android_media_MediaDrm_getSecureStops }, @@ -1408,4 +1427,3 @@ int register_android_media_Drm(JNIEnv *env) { return AndroidRuntime::registerNativeMethods(env, "android/media/MediaDrm", gMethods, NELEM(gMethods)); } -