Adds resume() function

o Revived resume() function to fix pause/resume bug. (Bug: 6663740)
o Mannually cherry-picked from GTV change.
(commit: ad1197226d1c6745959f0e469f510ca06f99489f)

Change-Id: I77ac90085fb1f1d2e7eb706642978a4fa4d28b49
diff --git a/include/media/stagefright/timedtext/TimedTextDriver.h b/include/media/stagefright/timedtext/TimedTextDriver.h
index cde551b..e705a04 100644
--- a/include/media/stagefright/timedtext/TimedTextDriver.h
+++ b/include/media/stagefright/timedtext/TimedTextDriver.h
@@ -40,6 +40,7 @@
 
     status_t start();
     status_t pause();
+    status_t resume();
     status_t selectTrack(size_t index);
     status_t unselectTrack(size_t index);
 
diff --git a/media/libstagefright/timedtext/TimedTextDriver.cpp b/media/libstagefright/timedtext/TimedTextDriver.cpp
index 42ca1f5..1a0dc7b 100644
--- a/media/libstagefright/timedtext/TimedTextDriver.cpp
+++ b/media/libstagefright/timedtext/TimedTextDriver.cpp
@@ -76,12 +76,12 @@
             return OK;
         case PAUSED:
             mPlayer->start();
-            break;
+            mState = PLAYING;
+            return OK;
         default:
             TRESPASS();
     }
-    mState = PLAYING;
-    return OK;
+    return UNKNOWN_ERROR;
 }
 
 // TODO: Test if pause() works properly.
@@ -95,14 +95,31 @@
             return INVALID_OPERATION;
         case PLAYING:
             mPlayer->pause();
-            break;
+            mState = PAUSED;
+            return OK;
         case PAUSED:
             return OK;
         default:
             TRESPASS();
     }
-    mState = PAUSED;
-    return OK;
+    return UNKNOWN_ERROR;
+}
+
+status_t TimedTextDriver::resume() {
+    Mutex::Autolock autoLock(mLock);
+    switch (mState) {
+        case UNINITIALIZED:
+            return INVALID_OPERATION;
+        case PLAYING:
+            return OK;
+        case PAUSED:
+            mPlayer->resume();
+            mState = PLAYING;
+            return OK;
+        default:
+            TRESPASS();
+    }
+    return UNKNOWN_ERROR;
 }
 
 status_t TimedTextDriver::selectTrack(size_t index) {
diff --git a/media/libstagefright/timedtext/TimedTextPlayer.cpp b/media/libstagefright/timedtext/TimedTextPlayer.cpp
index bf22db9..b9cac78 100644
--- a/media/libstagefright/timedtext/TimedTextPlayer.cpp
+++ b/media/libstagefright/timedtext/TimedTextPlayer.cpp
@@ -54,7 +54,7 @@
 
 void TimedTextPlayer::start() {
     sp<AMessage> msg = new AMessage(kWhatSeek, id());
-    msg->setInt64("seekTimeUs", -1);
+    msg->setInt64("seekTimeUs", kInvalidTimeUs);
     msg->post();
 }
 
@@ -62,6 +62,10 @@
     (new AMessage(kWhatPause, id()))->post();
 }
 
+void TimedTextPlayer::resume() {
+    (new AMessage(kWhatResume, id()))->post();
+}
+
 void TimedTextPlayer::seekToAsync(int64_t timeUs) {
     sp<AMessage> msg = new AMessage(kWhatSeek, id());
     msg->setInt64("seekTimeUs", timeUs);
@@ -80,7 +84,17 @@
             mSendSubtitleGeneration++;
             break;
         }
+        case kWhatResume: {
+            doRead();
+            break;
+        }
         case kWhatRetryRead: {
+            int32_t generation = -1;
+            CHECK(msg->findInt32("generation", &generation));
+            if (generation != mSendSubtitleGeneration) {
+                // Drop obsolete msg.
+                break;
+            }
             int64_t seekTimeUs;
             int seekMode;
             if (msg->findInt64("seekTimeUs", &seekTimeUs) &&
@@ -96,9 +110,12 @@
             break;
         }
         case kWhatSeek: {
-            int64_t seekTimeUs = 0;
+            mSendSubtitleGeneration++;
+            int64_t seekTimeUs = kInvalidTimeUs;
+            // Clear a displayed timed text before seeking.
+            notifyListener();
             msg->findInt64("seekTimeUs", &seekTimeUs);
-            if (seekTimeUs < 0) {
+            if (seekTimeUs == kInvalidTimeUs) {
                 sp<MediaPlayerBase> listener = mListener.promote();
                 if (listener != NULL) {
                     int32_t positionMs = 0;
@@ -113,8 +130,8 @@
             int32_t generation;
             CHECK(msg->findInt32("generation", &generation));
             if (generation != mSendSubtitleGeneration) {
-              // Drop obsolete msg.
-              break;
+                // Drop obsolete msg.
+                break;
             }
             // If current time doesn't reach to the fire time,
             // re-post the message with the adjusted delay time.
@@ -178,12 +195,14 @@
     if (err == WOULD_BLOCK) {
         sp<AMessage> msg = new AMessage(kWhatRetryRead, id());
         if (options != NULL) {
-            int64_t seekTimeUs;
-            MediaSource::ReadOptions::SeekMode seekMode;
+            int64_t seekTimeUs = kInvalidTimeUs;
+            MediaSource::ReadOptions::SeekMode seekMode =
+                MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC;
             CHECK(options->getSeekTo(&seekTimeUs, &seekMode));
             msg->setInt64("seekTimeUs", seekTimeUs);
             msg->setInt32("seekMode", seekMode);
         }
+        msg->setInt32("generation", mSendSubtitleGeneration);
         msg->post(kWaitTimeUsToRetryRead);
         return;
     } else if (err != OK) {
diff --git a/media/libstagefright/timedtext/TimedTextPlayer.h b/media/libstagefright/timedtext/TimedTextPlayer.h
index 08d4552..d8f83af 100644
--- a/media/libstagefright/timedtext/TimedTextPlayer.h
+++ b/media/libstagefright/timedtext/TimedTextPlayer.h
@@ -40,6 +40,7 @@
 
     void start();
     void pause();
+    void resume();
     void seekToAsync(int64_t timeUs);
     void setDataSource(sp<TimedTextSource> source);
 
@@ -50,6 +51,7 @@
     enum {
         kWhatPause = 'paus',
         kWhatSeek = 'seek',
+        kWhatResume = 'resm',
         kWhatRetryRead = 'read',
         kWhatSendSubtitle = 'send',
         kWhatSetSource = 'ssrc',