fixes for non-secure widevine playback

- separate secure decoding from widevine

- use non-blocking mode when reading from widevine source

- schedule buffer read when packet source is empty

bug: 18536934
Change-Id: I65a8e5e819975ca6900ed8e887a442940f2d5d38
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index e7a26b6..75a8f78 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -54,6 +54,7 @@
       mDurationUs(0ll),
       mAudioIsVorbis(false),
       mIsWidevine(false),
+      mIsSecure(false),
       mUIDValid(uidValid),
       mUID(uid),
       mFd(-1),
@@ -163,6 +164,17 @@
         if (mFileMeta->findInt64(kKeyDuration, &duration)) {
             mDurationUs = duration;
         }
+
+        if (!mIsWidevine) {
+            // Check mime to see if we actually have a widevine source.
+            // If the data source is not URL-type (eg. file source), we
+            // won't be able to tell until now.
+            const char *fileMime;
+            if (mFileMeta->findCString(kKeyMIMEType, &fileMime)
+                    && !strncasecmp(fileMime, "video/wvm", 9)) {
+                mIsWidevine = true;
+            }
+        }
     }
 
     int32_t totalBitrate = 0;
@@ -208,7 +220,7 @@
                 int32_t secure;
                 if (meta->findInt32(kKeyRequiresSecureBuffers, &secure)
                         && secure) {
-                    mIsWidevine = true;
+                    mIsSecure = true;
                     if (mUIDValid) {
                         extractor->setUID(mUID);
                     }
@@ -263,7 +275,7 @@
 
 status_t NuPlayer::GenericSource::setBuffers(
         bool audio, Vector<MediaBuffer *> &buffers) {
-    if (mIsWidevine && !audio) {
+    if (mIsSecure && !audio) {
         return mVideoTrack.mSource->setBuffers(buffers);
     }
     return INVALID_OPERATION;
@@ -293,6 +305,10 @@
 void NuPlayer::GenericSource::onPrepareAsync() {
     // delayed data source creation
     if (mDataSource == NULL) {
+        // set to false first, if the extractor
+        // comes back as secure, set it to true then.
+        mIsSecure = false;
+
         if (!mUri.empty()) {
             const char* uri = mUri.c_str();
             mIsWidevine = !strncasecmp(uri, "widevine://", 11);
@@ -312,8 +328,6 @@
                    mHTTPService, uri, &mUriHeaders, &mContentType,
                    static_cast<HTTPBase *>(mHttpSource.get()));
         } else {
-            // set to false first, if the extractor
-            // comes back as secure, set it to true then.
             mIsWidevine = false;
 
             mDataSource = new FileSource(mFd, mOffset, mLength);
@@ -368,7 +382,7 @@
     }
 
     notifyFlagsChanged(
-            (mIsWidevine ? FLAG_SECURE : 0)
+            (mIsSecure ? FLAG_SECURE : 0)
             | FLAG_CAN_PAUSE
             | FLAG_CAN_SEEK_BACKWARD
             | FLAG_CAN_SEEK_FORWARD
@@ -485,8 +499,8 @@
     // nothing to do, just account for DRM playback status
     setDrmPlaybackStatusIfNeeded(Playback::STOP, 0);
     mStarted = false;
-    if (mIsWidevine) {
-        // For a widevine source we need to prevent any further reads.
+    if (mIsWidevine || mIsSecure) {
+        // For widevine or secure sources we need to prevent any further reads.
         sp<AMessage> msg = new AMessage(kWhatStopWidevine, id());
         sp<AMessage> response;
         (void) msg->postAndAwaitResponse(&response);
@@ -846,7 +860,12 @@
 
     status_t finalResult;
     if (!track->mPackets->hasBufferAvailable(&finalResult)) {
-        return (finalResult == OK ? -EWOULDBLOCK : finalResult);
+        if (finalResult == OK) {
+            postReadBuffer(
+                    audio ? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO);
+            return -EWOULDBLOCK;
+        }
+        return finalResult;
     }
 
     status_t result = track->mPackets->dequeueAccessUnit(accessUnit);
@@ -1188,7 +1207,7 @@
     }
 
     sp<ABuffer> ab;
-    if (mIsWidevine && !audio) {
+    if (mIsSecure && !audio) {
         // data is already provided in the buffer
         ab = new ABuffer(NULL, mb->range_length());
         mb->add_ref();
@@ -1257,14 +1276,13 @@
     int32_t tmpType;
     CHECK(msg->findInt32("trackType", &tmpType));
     media_track_type trackType = (media_track_type)tmpType;
+    readBuffer(trackType);
     {
         // only protect the variable change, as readBuffer may
-        // take considerable time.  This may result in one extra
-        // read being processed, but that is benign.
+        // take considerable time.
         Mutex::Autolock _l(mReadBufferLock);
         mPendingReadBufferTypes &= ~(1 << trackType);
     }
-    readBuffer(trackType);
 }
 
 void NuPlayer::GenericSource::readBuffer(
@@ -1317,7 +1335,7 @@
         seeking = true;
     }
 
-    if (mIsWidevine && trackType != MEDIA_TRACK_TYPE_AUDIO) {
+    if (mIsWidevine) {
         options.setNonBlocking();
     }