mediaplayer: ensure secure decoders are instantiated before starting source

Bug: 19984798
Change-Id: Iff13cf03c4ce3141380f4d7ab4a2b1045c5ce747
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index a040343..5a31b74 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -265,6 +265,12 @@
         }
     }
 
+    mBitrate = totalBitrate;
+
+    return OK;
+}
+
+status_t NuPlayer::GenericSource::startSources() {
     // Start the selected A/V tracks now before we start buffering.
     // Widevine sources might re-initialize crypto when starting, if we delay
     // this to start(), all data buffered during prepare would be wasted.
@@ -279,8 +285,6 @@
         return UNKNOWN_ERROR;
     }
 
-    mBitrate = totalBitrate;
-
     return OK;
 }
 
@@ -415,6 +419,32 @@
             | FLAG_CAN_SEEK_FORWARD
             | FLAG_CAN_SEEK);
 
+    if (mIsSecure) {
+        // secure decoders must be instantiated before starting widevine source
+        sp<AMessage> reply = new AMessage(kWhatSecureDecodersInstantiated, this);
+        notifyInstantiateSecureDecoders(reply);
+    } else {
+        finishPrepareAsync();
+    }
+}
+
+void NuPlayer::GenericSource::onSecureDecodersInstantiated(status_t err) {
+    if (err != OK) {
+        ALOGE("Failed to instantiate secure decoders!");
+        notifyPreparedAndCleanup(err);
+        return;
+    }
+    finishPrepareAsync();
+}
+
+void NuPlayer::GenericSource::finishPrepareAsync() {
+    status_t err = startSources();
+    if (err != OK) {
+        ALOGE("Failed to init start data source!");
+        notifyPreparedAndCleanup(err);
+        return;
+    }
+
     if (mIsStreaming) {
         mPrepareBuffering = true;
 
@@ -430,6 +460,7 @@
         mDataSource.clear();
         mCachedSource.clear();
         mHttpSource.clear();
+        mBitrate = -1;
 
         cancelPollBuffering();
     }
@@ -805,6 +836,14 @@
           break;
       }
 
+      case kWhatSecureDecodersInstantiated:
+      {
+          int32_t err;
+          CHECK(msg->findInt32("err", &err));
+          onSecureDecodersInstantiated(err);
+          break;
+      }
+
       case kWhatStopWidevine:
       {
           // mStopRead is only used for Widevine to prevent the video source