Add support for ANDROID_LOOP to NuPlayer

Bug: 17518139
Change-Id: I9355ddd4c998d967013dd8bd32d670a9a83dea31
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 511871d..d194e73 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -106,6 +106,10 @@
     return OK;
 }
 
+sp<MetaData> NuPlayer::GenericSource::getFileFormatMeta() const {
+    return mFileMeta;
+}
+
 status_t NuPlayer::GenericSource::initFromDataSource() {
     sp<MediaExtractor> extractor;
 
@@ -144,10 +148,10 @@
         checkDrmStatus(mDataSource);
     }
 
-    sp<MetaData> fileMeta = extractor->getMetaData();
-    if (fileMeta != NULL) {
+    mFileMeta = extractor->getMetaData();
+    if (mFileMeta != NULL) {
         int64_t duration;
-        if (fileMeta->findInt64(kKeyDuration, &duration)) {
+        if (mFileMeta->findInt64(kKeyDuration, &duration)) {
             mDurationUs = duration;
         }
     }
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h
index c70c48e..dcdfb0a 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.h
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.h
@@ -57,6 +57,8 @@
 
     virtual status_t feedMoreTSData();
 
+    virtual sp<MetaData> getFileFormatMeta() const;
+
     virtual status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit);
 
     virtual status_t getDuration(int64_t *durationUs);
@@ -123,6 +125,7 @@
     sp<DataSource> mDataSource;
     sp<NuCachedSource2> mCachedSource;
     sp<WVMExtractor> mWVMExtractor;
+    sp<MetaData> mFileMeta;
     DrmManagerClient *mDrmManagerClient;
     sp<DecryptHandle> mDecryptHandle;
     bool mStarted;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 9020a8d..4bb7c96 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -1720,6 +1720,10 @@
     return err;
 }
 
+sp<MetaData> NuPlayer::getFileMeta() {
+    return mSource->getFileFormatMeta();
+}
+
 void NuPlayer::schedulePollDuration() {
     sp<AMessage> msg = new AMessage(kWhatPollDuration, id());
     msg->setInt32("generation", mPollDurationGeneration);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index 2e951bd..7197e5f 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -67,6 +67,8 @@
     status_t getSelectedTrack(int32_t type, Parcel* reply) const;
     status_t selectTrack(size_t trackIndex, bool select);
 
+    sp<MetaData> getFileMeta();
+
     static const size_t kAggregateBufferSizeBytes;
 
 protected:
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 7dd54c1..69aa7b3 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -45,6 +45,7 @@
       mPlayerFlags(0),
       mAtEOS(false),
       mLooping(false),
+      mAutoLoop(false),
       mStartupSeekTimeUs(-1) {
     mLooper->setName("NuPlayerDriver Looper");
 
@@ -498,6 +499,7 @@
 
 void NuPlayerDriver::setAudioSink(const sp<AudioSink> &audioSink) {
     mPlayer->setAudioSink(audioSink);
+    mAudioSink = audioSink;
 }
 
 status_t NuPlayerDriver::setParameter(
@@ -627,7 +629,8 @@
         case MEDIA_PLAYBACK_COMPLETE:
         {
             if (mState != STATE_RESET_IN_PROGRESS) {
-                if (mLooping) {
+                if (mLooping || (mAutoLoop
+                        && (mAudioSink == NULL || mAudioSink->realtime()))) {
                     mPlayer->seekToAsync(0);
                     break;
                 }
@@ -693,6 +696,13 @@
         }
     }
 
+    sp<MetaData> meta = mPlayer->getFileMeta();
+    int32_t loop;
+    if (meta != NULL
+            && meta->findInt32(kKeyAutoLoop, &loop) && loop != 0) {
+        mAutoLoop = true;
+    }
+
     mCondition.broadcast();
 }
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
index e81d605..f2bd431 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
@@ -114,10 +114,12 @@
 
     sp<ALooper> mLooper;
     sp<NuPlayer> mPlayer;
+    sp<AudioSink> mAudioSink;
     uint32_t mPlayerFlags;
 
     bool mAtEOS;
     bool mLooping;
+    bool mAutoLoop;
 
     int64_t mStartupSeekTimeUs;
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
index 7ccf3b1..a2d9b2f 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
@@ -73,6 +73,7 @@
 
     virtual sp<AMessage> getFormat(bool audio);
     virtual sp<MetaData> getFormatMeta(bool /* audio */) { return NULL; }
+    virtual sp<MetaData> getFileFormatMeta() const { return NULL; }
 
     virtual status_t dequeueAccessUnit(
             bool audio, sp<ABuffer> *accessUnit) = 0;