Merge "MediaDrm API: Add two exceptions to handle error path scenarios" into jb-mr2-dev
diff --git a/api/current.txt b/api/current.txt
index 3418761..1166546 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11497,6 +11497,10 @@
field public static final int QUALITY_MEDIUM = 1; // 0x1
}
+ public final class DeniedByServerException extends android.media.MediaDrmException {
+ ctor public DeniedByServerException(java.lang.String);
+ }
+
public class ExifInterface {
ctor public ExifInterface(java.lang.String) throws java.io.IOException;
method public double getAltitude(double);
@@ -11818,18 +11822,18 @@
}
public final class MediaDrm {
- ctor public MediaDrm(java.util.UUID) throws android.media.MediaDrmException;
+ ctor public MediaDrm(java.util.UUID) throws android.media.UnsupportedSchemeException;
method public void closeSession(byte[]);
method public android.media.MediaDrm.CryptoSession getCryptoSession(byte[], java.lang.String, java.lang.String);
- method public android.media.MediaDrm.KeyRequest getKeyRequest(byte[], byte[], java.lang.String, int, java.util.HashMap<java.lang.String, java.lang.String>);
+ method public android.media.MediaDrm.KeyRequest getKeyRequest(byte[], byte[], java.lang.String, int, java.util.HashMap<java.lang.String, java.lang.String>) throws android.media.NotProvisionedException;
method public byte[] getPropertyByteArray(java.lang.String);
method public java.lang.String getPropertyString(java.lang.String);
method public android.media.MediaDrm.ProvisionRequest getProvisionRequest();
method public java.util.List<byte[]> getSecureStops();
method public static final boolean isCryptoSchemeSupported(java.util.UUID);
- method public byte[] openSession();
- method public byte[] provideKeyResponse(byte[], byte[]);
- method public void provideProvisionResponse(byte[]);
+ method public byte[] openSession() throws android.media.NotProvisionedException;
+ method public byte[] provideKeyResponse(byte[], byte[]) throws android.media.DeniedByServerException, android.media.NotProvisionedException;
+ method public void provideProvisionResponse(byte[]) throws android.media.DeniedByServerException;
method public java.util.HashMap<java.lang.String, java.lang.String> queryKeyStatus(byte[]);
method public final void release();
method public void releaseSecureStops(byte[]);
@@ -11873,7 +11877,7 @@
method public java.lang.String getDefaultUrl();
}
- public final class MediaDrmException extends java.lang.Exception {
+ public class MediaDrmException extends java.lang.Exception {
ctor public MediaDrmException(java.lang.String);
}
@@ -12339,6 +12343,10 @@
field public static final int SYNC_EVENT_PRESENTATION_COMPLETE = 1; // 0x1
}
+ public final class NotProvisionedException extends android.media.MediaDrmException {
+ ctor public NotProvisionedException(java.lang.String);
+ }
+
public class RemoteControlClient {
ctor public RemoteControlClient(android.app.PendingIntent);
ctor public RemoteControlClient(android.app.PendingIntent, android.os.Looper);
@@ -12581,6 +12589,10 @@
field public static final int TONE_SUP_RINGTONE = 23; // 0x17
}
+ public final class UnsupportedSchemeException extends android.media.MediaDrmException {
+ ctor public UnsupportedSchemeException(java.lang.String);
+ }
+
}
package android.media.audiofx {
diff --git a/media/java/android/media/DeniedByServerException.java b/media/java/android/media/DeniedByServerException.java
new file mode 100644
index 0000000..9c1633a
--- /dev/null
+++ b/media/java/android/media/DeniedByServerException.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2013 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 android.media;
+
+/**
+ * Exception thrown when the provisioning server or key server denies a
+ * certficate or license for a device.
+ */
+public final class DeniedByServerException extends MediaDrmException {
+ public DeniedByServerException(String detailMessage) {
+ super(detailMessage);
+ }
+}
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index a58fa51..be2d9bc 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -127,11 +127,14 @@
private static final native boolean isCryptoSchemeSupportedNative(byte[] uuid);
/**
- * Instantiate a MediaDrm object using opaque, crypto scheme specific
- * data.
+ * Instantiate a MediaDrm object
+ *
* @param uuid The UUID of the crypto scheme.
+ *
+ * @throws UnsupportedSchemeException if the device does not support the
+ * specified scheme UUID
*/
- public MediaDrm(UUID uuid) throws MediaDrmException {
+ public MediaDrm(UUID uuid) throws UnsupportedSchemeException {
Looper looper;
if ((looper = Looper.myLooper()) != null) {
mEventHandler = new EventHandler(this, looper);
@@ -268,8 +271,10 @@
/**
* Open a new session with the MediaDrm object. A session ID is returned.
+ *
+ * @throws NotProvisionedException if provisioning is needed
*/
- public native byte[] openSession();
+ public native byte[] openSession() throws NotProvisionedException;
/**
* Close a session on the MediaDrm object that was previously opened
@@ -346,10 +351,14 @@
* keys, which are identified by a keySetId.
* @param optionalParameters are included in the key request message to
* allow a client application to provide additional message parameters to the server.
+ *
+ * @throws NotProvisionedException if reprovisioning is needed, due to a
+ * problem with the certifcate
*/
public native KeyRequest getKeyRequest(byte[] scope, byte[] init,
String mimeType, int keyType,
- HashMap<String, String> optionalParameters);
+ HashMap<String, String> optionalParameters)
+ throws NotProvisionedException;
/**
@@ -360,8 +369,15 @@
*
* @param sessionId the session ID for the DRM session
* @param response the byte array response from the server
+ *
+ * @throws NotProvisionedException if the response indicates that
+ * reprovisioning is required
+ * @throws DeniedByServerException if the response indicates that the
+ * server rejected the request
*/
- public native byte[] provideKeyResponse(byte[] sessionId, byte[] response);
+ public native byte[] provideKeyResponse(byte[] sessionId, byte[] response)
+ throws NotProvisionedException, DeniedByServerException;
+
/**
* Restore persisted offline keys into a new session. keySetId identifies the
@@ -430,8 +446,12 @@
*
* @param response the opaque provisioning response byte array to provide to the
* DRM engine plugin.
+ *
+ * @throws DeniedByServerException if the response indicates that the
+ * server rejected the request
*/
- public native void provideProvisionResponse(byte[] response);
+ public native void provideProvisionResponse(byte[] response)
+ throws DeniedByServerException;
/**
* A means of enforcing limits on the number of concurrent streams per subscriber
diff --git a/media/java/android/media/MediaDrmException.java b/media/java/android/media/MediaDrmException.java
index d6f5ff4..d547574 100644
--- a/media/java/android/media/MediaDrmException.java
+++ b/media/java/android/media/MediaDrmException.java
@@ -17,10 +17,9 @@
package android.media;
/**
- * Exception thrown if MediaDrm object could not be instantiated for
- * whatever reason.
+ * Base class for MediaDrm exceptions
*/
-public final class MediaDrmException extends Exception {
+public class MediaDrmException extends Exception {
public MediaDrmException(String detailMessage) {
super(detailMessage);
}
diff --git a/media/java/android/media/NotProvisionedException.java b/media/java/android/media/NotProvisionedException.java
new file mode 100644
index 0000000..32b8151
--- /dev/null
+++ b/media/java/android/media/NotProvisionedException.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2013 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 android.media;
+
+/**
+ * Exception thrown when an operation on a MediaDrm object is attempted
+ * and the device does not have a certificate. The app should obtain and
+ * install a certificate using the MediaDrm provisioning methods then retry
+ * the operation.
+ */
+public final class NotProvisionedException extends MediaDrmException {
+ public NotProvisionedException(String detailMessage) {
+ super(detailMessage);
+ }
+}
diff --git a/media/java/android/media/UnsupportedSchemeException.java b/media/java/android/media/UnsupportedSchemeException.java
new file mode 100644
index 0000000..d7b5d47
--- /dev/null
+++ b/media/java/android/media/UnsupportedSchemeException.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2013 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 android.media;
+
+/**
+ * Exception thrown when an attempt is made to construct a MediaDrm object
+ * using a crypto scheme UUID that is not supported by the device
+ */
+public final class UnsupportedSchemeException extends MediaDrmException {
+ public UnsupportedSchemeException(String detailMessage) {
+ super(detailMessage);
+ }
+}
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index d1b499e..ec88949 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -219,12 +219,6 @@
case ERROR_DRM_TAMPER_DETECTED:
drmMessage = "Invalid state";
break;
- case ERROR_DRM_NOT_PROVISIONED:
- drmMessage = "Not provisioned";
- break;
- case ERROR_DRM_DEVICE_REVOKED:
- drmMessage = "Device revoked";
- break;
default:
break;
}
@@ -238,6 +232,12 @@
if (err == BAD_VALUE) {
jniThrowException(env, "java/lang/IllegalArgumentException", msg);
return true;
+ } else if (err == ERROR_DRM_NOT_PROVISIONED) {
+ jniThrowException(env, "android/media/NotProvisionedException", msg);
+ return true;
+ } else if (err == ERROR_DRM_DEVICE_REVOKED) {
+ jniThrowException(env, "android/media/DeniedByServerException", msg);
+ return true;
} else if (err != OK) {
String8 errbuf;
if (drmMessage != NULL) {
@@ -248,6 +248,7 @@
msg = errbuf.string();
}
}
+ ALOGE("Illegal state exception: %s", msg);
jniThrowException(env, "java/lang/IllegalStateException", msg);
return true;
}
@@ -574,7 +575,7 @@
if (err != OK) {
jniThrowException(
env,
- "android/media/MediaDrmException",
+ "android/media/UnsupportedSchemeException",
"Failed to instantiate drm object.");
return;
}