Bug 1307818-[P3] Notify correct batched-keystatuses-changed information in API V23+. draft
authorKilik Kuo <kikuo@mozilla.com>
Wed, 16 Nov 2016 22:10:43 +0800
changeset 439724 8032a4a22cb21744f918891a3b74a0a60a983700
parent 439723 3ba77475e01f76d293cfd35d98e57a9842742cb0
child 537231 89484f6ed390726cb5b730d862abe4fdaddb51e4
push id36071
push userkikuo@mozilla.com
push dateWed, 16 Nov 2016 14:19:26 +0000
bugs1307818
milestone52.0a1
Bug 1307818-[P3] Notify correct batched-keystatuses-changed information in API V23+. MozReview-Commit-ID: CYQ7BoJim7W
mobile/android/base/java/org/mozilla/gecko/media/GeckoMediaDrmBridgeV21.java
mobile/android/base/java/org/mozilla/gecko/media/GeckoMediaDrmBridgeV23.java
--- a/mobile/android/base/java/org/mozilla/gecko/media/GeckoMediaDrmBridgeV21.java
+++ b/mobile/android/base/java/org/mozilla/gecko/media/GeckoMediaDrmBridgeV21.java
@@ -16,24 +16,26 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.UUID;
 import java.util.ArrayDeque;
 
 import android.annotation.SuppressLint;
 import android.os.AsyncTask;
 import android.os.Handler;
 import android.os.HandlerThread;
+import android.media.DeniedByServerException;
 import android.media.MediaCrypto;
 import android.media.MediaCryptoException;
 import android.media.MediaDrm;
 import android.media.MediaDrmException;
+import android.media.NotProvisionedException;
 import android.util.Log;
 
 public class GeckoMediaDrmBridgeV21 implements GeckoMediaDrm {
-    private static final String LOGTAG = "GeckoMediaDrmBridgeV21";
+    protected final String LOGTAG;
     private static final String INVALID_SESSION_ID = "Invalid";
     private static final String WIDEVINE_KEY_SYSTEM = "com.widevine.alpha";
     private static final boolean DEBUG = false;
     private static final UUID WIDEVINE_SCHEME_UUID =
         new UUID(0xedef8ba979d64aceL, 0xa3c827dcd51d21edL);
     // MediaDrm.KeyStatus information listener is supported on M+, adding a
     // dummy key id to report key status.
     private static final byte[] DUMMY_KEY_ID = new byte[] {0};
@@ -93,17 +95,18 @@ public class GeckoMediaDrmBridgeV21 impl
         mDrm.setPropertyString("securityLevel", "L3");
         // Refer to chromium, set multi-session mode for Widevine.
         if (mSchemeUUID.equals(WIDEVINE_SCHEME_UUID)) {
             mDrm.setPropertyString("sessionSharing", "enable");
         }
     }
 
     GeckoMediaDrmBridgeV21(String keySystem) throws Exception {
-        if (DEBUG) Log.d(LOGTAG, "GeckoMediaDrmBridgeV21()");
+        LOGTAG = getClass().getSimpleName();
+        if (DEBUG) Log.d(LOGTAG, "GeckoMediaDrmBridgeV21 ctor");
 
         mProvisioningPromiseId = 0;
         mSessionIds = new HashSet<ByteBuffer>();
         mSessionMIMETypes = new HashMap<ByteBuffer, String>();
         mPendingCreateSessionDataQueue = new ArrayDeque<PendingCreateSessionData>();
 
         mSchemeUUID = convertKeySystemToSchemeUUID(keySystem);
         mCryptoSessionId = null;
@@ -213,28 +216,20 @@ public class GeckoMediaDrmBridgeV21 impl
             }
             SessionKeyInfo[] keyInfos = new SessionKeyInfo[1];
             keyInfos[0] = new SessionKeyInfo(DUMMY_KEY_ID,
                                              MediaDrm.KeyStatus.STATUS_USABLE);
             onSessionBatchedKeyChanged(session.array(), keyInfos);
             if (DEBUG) Log.d(LOGTAG, "Key successfully added for session " + sessionId);
             onSessionUpdated(promiseId, session.array());
             return;
-        } catch (android.media.NotProvisionedException e) {
-            if (DEBUG) Log.d(LOGTAG, "Failed to provide key response:" + e.getMessage());
-            onSessionError(session.array(), "Got NotProvisionedException.");
-            onRejectPromise(promiseId, "Not provisioned during updateSession.");
-        } catch (android.media.DeniedByServerException e) {
-            if (DEBUG) Log.d(LOGTAG, "Failed to provide key response:" + e.getMessage());
-            onSessionError(session.array(), "Got DeniedByServerException.");
-            onRejectPromise(promiseId, "Denied by server during updateSession.");
-        } catch (java.lang.IllegalStateException e) {
-            if (DEBUG) Log.d(LOGTAG, "Exception when calling provideKeyResponse():" + e.getMessage());
-            onSessionError(session.array(), "Got IllegalStateException.");
-            onRejectPromise(promiseId, "Rejected during updateSession.");
+        } catch (final NotProvisionedException | DeniedByServerException | IllegalStateException e) {
+            if (DEBUG) Log.d(LOGTAG, "Failed to provide key response:", e);
+            onSessionError(session.array(), "Got exception during updateSession.");
+            onRejectPromise(promiseId, "Got exception during updateSession.");
         }
         release();
         return;
     }
 
     @Override
     public void closeSession(int promiseId, String sessionId) {
         if (DEBUG) Log.d(LOGTAG, "closeSession()");
@@ -409,17 +404,17 @@ public class GeckoMediaDrmBridgeV21 impl
         } catch (android.media.MediaDrmException e) {
             // Other MediaDrmExceptions (e.g. ResourceBusyException) are not
             // recoverable.
             release();
             return null;
         }
     }
 
-    private boolean sessionExists(ByteBuffer session) {
+    protected boolean sessionExists(ByteBuffer session) {
         if (mCryptoSessionId == null) {
             if (DEBUG) Log.d(LOGTAG, "Session doesn't exist because media crypto session is not created.");
             return false;
         }
         if (session == null) {
             if (DEBUG) Log.d(LOGTAG, "Session is null, not in map !");
             return false;
         }
--- a/mobile/android/base/java/org/mozilla/gecko/media/GeckoMediaDrmBridgeV23.java
+++ b/mobile/android/base/java/org/mozilla/gecko/media/GeckoMediaDrmBridgeV23.java
@@ -1,23 +1,27 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.media;
 
 import android.annotation.TargetApi;
+import android.media.DeniedByServerException;
+import android.media.NotProvisionedException;
+
 import static android.os.Build.VERSION_CODES.M;
 import android.media.MediaDrm;
 import android.util.Log;
+import java.lang.IllegalStateException;
+import java.nio.ByteBuffer;
+import java.util.HashMap;
 import java.util.List;
 
 public class GeckoMediaDrmBridgeV23 extends GeckoMediaDrmBridgeV21 {
-
-    private static final String LOGTAG = "GeckoMediaDrmBridgeV23";
     private static final boolean DEBUG = false;
 
     GeckoMediaDrmBridgeV23(String keySystem) throws Exception {
         super(keySystem);
         if (DEBUG) Log.d(LOGTAG, "GeckoMediaDrmBridgeV23 ctor");
         mDrm.setOnKeyStatusChangeListener(new KeyStatusChangeListener(), null);
     }
 
@@ -34,11 +38,48 @@ public class GeckoMediaDrmBridgeV23 exte
             }
             SessionKeyInfo[] keyInfos = new SessionKeyInfo[keyInformation.size()];
             for (int i = 0; i < keyInformation.size(); i++) {
                 MediaDrm.KeyStatus keyStatus = keyInformation.get(i);
                 keyInfos[i] = new SessionKeyInfo(keyStatus.getKeyId(),
                                                  keyStatus.getStatusCode());
             }
             onSessionBatchedKeyChanged(sessionId, keyInfos);
+            if (DEBUG) Log.d(LOGTAG, "Key successfully added for session " + new String(sessionId));
         }
     }
+
+    @Override
+    public void updateSession(int promiseId,
+                              String sessionId,
+                              byte[] response) {
+        if (DEBUG) Log.d(LOGTAG, "updateSession(), sessionId = " + sessionId);
+        if (mDrm == null) {
+            onRejectPromise(promiseId, "MediaDrm instance doesn't exist !!");
+            return;
+        }
+
+        ByteBuffer session = ByteBuffer.wrap(sessionId.getBytes());
+        if (!sessionExists(session)) {
+            onRejectPromise(promiseId, "Invalid session during updateSession.");
+            return;
+        }
+
+        try {
+            final byte [] keySetId = mDrm.provideKeyResponse(session.array(), response);
+            if (DEBUG) {
+                HashMap<String, String> infoMap = mDrm.queryKeyStatus(session.array());
+                for (String strKey : infoMap.keySet()) {
+                    String strValue = infoMap.get(strKey);
+                    Log.d(LOGTAG, "InfoMap : key(" + strKey + ")/value(" + strValue + ")");
+                }
+            }
+            onSessionUpdated(promiseId, session.array());
+            return;
+        } catch (final NotProvisionedException | DeniedByServerException | IllegalStateException e) {
+            if (DEBUG) Log.d(LOGTAG, "Failed to provide key response:", e);
+            onSessionError(session.array(), "Got exception during updateSession.");
+            onRejectPromise(promiseId, "Got exception during updateSession.");
+        }
+        release();
+        return;
+    }
 }