Groundwork to support bidirectional, asynchronous communication

between NuPlayer and its sources.

Change-Id: I1989022d806206b926555add3aa5c1fcf37aa78d
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index f281879..450fae5 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -32,11 +32,13 @@
 namespace android {
 
 NuPlayer::GenericSource::GenericSource(
+        const sp<AMessage> &notify,
         const char *url,
         const KeyedVector<String8, String8> *headers,
         bool uidValid,
         uid_t uid)
-    : mDurationUs(0ll),
+    : Source(notify),
+      mDurationUs(0ll),
       mAudioIsVorbis(false) {
     DataSource::RegisterDefaultSniffers();
 
@@ -48,8 +50,10 @@
 }
 
 NuPlayer::GenericSource::GenericSource(
+        const sp<AMessage> &notify,
         int fd, int64_t offset, int64_t length)
-    : mDurationUs(0ll),
+    : Source(notify),
+      mDurationUs(0ll),
       mAudioIsVorbis(false) {
     DataSource::RegisterDefaultSniffers();
 
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h
index e1ce2c1..e59ea3a 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.h
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.h
@@ -32,12 +32,15 @@
 
 struct NuPlayer::GenericSource : public NuPlayer::Source {
     GenericSource(
+            const sp<AMessage> &notify,
             const char *url,
             const KeyedVector<String8, String8> *headers,
             bool uidValid = false,
             uid_t uid = 0);
 
-    GenericSource(int fd, int64_t offset, int64_t length);
+    GenericSource(
+            const sp<AMessage> &notify,
+            int fd, int64_t offset, int64_t length);
 
     virtual void start();
 
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
index 5dcca12..d38ee62 100644
--- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
@@ -34,10 +34,12 @@
 namespace android {
 
 NuPlayer::HTTPLiveSource::HTTPLiveSource(
+        const sp<AMessage> &notify,
         const char *url,
         const KeyedVector<String8, String8> *headers,
         bool uidValid, uid_t uid)
-    : mURL(url),
+    : Source(notify),
+      mURL(url),
       mUIDValid(uidValid),
       mUID(uid),
       mFlags(0),
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
index 79f4ab8..4a217af 100644
--- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
+++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.h
@@ -28,6 +28,7 @@
 
 struct NuPlayer::HTTPLiveSource : public NuPlayer::Source {
     HTTPLiveSource(
+            const sp<AMessage> &notify,
             const char *url,
             const KeyedVector<String8, String8> *headers,
             bool uidValid = false,
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 517fb34..9585aba 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -145,12 +145,14 @@
 void NuPlayer::setDataSource(const sp<IStreamSource> &source) {
     sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
 
+    sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
+
     char prop[PROPERTY_VALUE_MAX];
     if (property_get("media.stagefright.use-mp4source", prop, NULL)
             && (!strcmp(prop, "1") || !strcasecmp(prop, "true"))) {
-        msg->setObject("source", new MP4Source(source));
+        msg->setObject("source", new MP4Source(notify, source));
     } else {
-        msg->setObject("source", new StreamingSource(source));
+        msg->setObject("source", new StreamingSource(notify, source));
     }
 
     msg->post();
@@ -176,13 +178,15 @@
         const char *url, const KeyedVector<String8, String8> *headers) {
     sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
 
+    sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
+
     sp<Source> source;
     if (IsHTTPLiveURL(url)) {
-        source = new HTTPLiveSource(url, headers, mUIDValid, mUID);
+        source = new HTTPLiveSource(notify, url, headers, mUIDValid, mUID);
     } else if (!strncasecmp(url, "rtsp://", 7)) {
-        source = new RTSPSource(url, headers, mUIDValid, mUID);
+        source = new RTSPSource(notify, url, headers, mUIDValid, mUID);
     } else {
-        source = new GenericSource(url, headers, mUIDValid, mUID);
+        source = new GenericSource(notify, url, headers, mUIDValid, mUID);
     }
 
     msg->setObject("source", source);
@@ -192,7 +196,9 @@
 void NuPlayer::setDataSource(int fd, int64_t offset, int64_t length) {
     sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
 
-    sp<Source> source = new GenericSource(fd, offset, length);
+    sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());
+
+    sp<Source> source = new GenericSource(notify, fd, offset, length);
     msg->setObject("source", source);
     msg->post();
 }
@@ -273,6 +279,8 @@
             CHECK(msg->findObject("source", &obj));
 
             mSource = static_cast<Source *>(obj.get());
+
+            looper()->registerHandler(mSource);
             break;
         }
 
@@ -714,6 +722,12 @@
             break;
         }
 
+        case kWhatSourceNotify:
+        {
+            TRESPASS();  // TBD
+            break;
+        }
+
         default:
             TRESPASS();
             break;
@@ -1169,6 +1183,9 @@
 
     if (mSource != NULL) {
         mSource->stop();
+
+        looper()->unregisterHandler(mSource->id());
+
         mSource.clear();
     }
 
@@ -1210,4 +1227,10 @@
     }
 }
 
+////////////////////////////////////////////////////////////////////////////////
+
+void NuPlayer::Source::onMessageReceived(const sp<AMessage> &msg) {
+    TRESPASS();
+}
+
 }  // namespace android
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index 09fc0ba..0ff6089 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -95,6 +95,7 @@
         kWhatPause                      = 'paus',
         kWhatResume                     = 'rsme',
         kWhatPollDuration               = 'polD',
+        kWhatSourceNotify               = 'srcN',
     };
 
     wp<NuPlayerDriver> mDriver;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
index a635340..a3201cf 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
@@ -20,17 +20,23 @@
 
 #include "NuPlayer.h"
 
+#include <media/stagefright/foundation/AMessage.h>
+
 namespace android {
 
 struct ABuffer;
 
-struct NuPlayer::Source : public RefBase {
+struct NuPlayer::Source : public AHandler {
     enum Flags {
         FLAG_SEEKABLE           = 1,
         FLAG_DYNAMIC_DURATION   = 2,
     };
 
-    Source() {}
+    // The provides message is used to notify the player about various
+    // events.
+    Source(const sp<AMessage> &notify)
+        : mNotify(notify) {
+    }
 
     virtual void start() = 0;
     virtual void stop() {}
@@ -57,9 +63,15 @@
 protected:
     virtual ~Source() {}
 
+    virtual void onMessageReceived(const sp<AMessage> &msg);
+
     virtual sp<MetaData> getFormatMeta(bool audio) { return NULL; }
 
+    sp<AMessage> dupNotify() const { return mNotify->dup(); }
+
 private:
+    sp<AMessage> mNotify;
+
     DISALLOW_EVIL_CONSTRUCTORS(Source);
 };
 
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
index afaa5db..e402115 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
@@ -29,11 +29,13 @@
 namespace android {
 
 NuPlayer::RTSPSource::RTSPSource(
+        const sp<AMessage> &notify,
         const char *url,
         const KeyedVector<String8, String8> *headers,
         bool uidValid,
         uid_t uid)
-    : mURL(url),
+    : Source(notify),
+      mURL(url),
       mUIDValid(uidValid),
       mUID(uid),
       mFlags(0),
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.h b/media/libmediaplayerservice/nuplayer/RTSPSource.h
index 779d791..033b3e8 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.h
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.h
@@ -32,6 +32,7 @@
 
 struct NuPlayer::RTSPSource : public NuPlayer::Source {
     RTSPSource(
+            const sp<AMessage> &notify,
             const char *url,
             const KeyedVector<String8, String8> *headers,
             bool uidValid = false,
diff --git a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
index 7159404..9b04833 100644
--- a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
@@ -32,8 +32,11 @@
 
 namespace android {
 
-NuPlayer::StreamingSource::StreamingSource(const sp<IStreamSource> &source)
-    : mSource(source),
+NuPlayer::StreamingSource::StreamingSource(
+        const sp<AMessage> &notify,
+        const sp<IStreamSource> &source)
+    : Source(notify),
+      mSource(source),
       mFinalResult(OK) {
 }
 
diff --git a/media/libmediaplayerservice/nuplayer/StreamingSource.h b/media/libmediaplayerservice/nuplayer/StreamingSource.h
index a27b58a..dc616f7 100644
--- a/media/libmediaplayerservice/nuplayer/StreamingSource.h
+++ b/media/libmediaplayerservice/nuplayer/StreamingSource.h
@@ -27,7 +27,9 @@
 struct ATSParser;
 
 struct NuPlayer::StreamingSource : public NuPlayer::Source {
-    StreamingSource(const sp<IStreamSource> &source);
+    StreamingSource(
+            const sp<AMessage> &notify,
+            const sp<IStreamSource> &source);
 
     virtual void start();
 
diff --git a/media/libmediaplayerservice/nuplayer/mp4/MP4Source.cpp b/media/libmediaplayerservice/nuplayer/mp4/MP4Source.cpp
index a62d5a2..d659b73 100644
--- a/media/libmediaplayerservice/nuplayer/mp4/MP4Source.cpp
+++ b/media/libmediaplayerservice/nuplayer/mp4/MP4Source.cpp
@@ -104,8 +104,10 @@
     DISALLOW_EVIL_CONSTRUCTORS(StreamSource);
 };
 
-MP4Source::MP4Source(const sp<IStreamSource> &source)
-    : mSource(source),
+MP4Source::MP4Source(
+        const sp<AMessage> &notify, const sp<IStreamSource> &source)
+    : Source(notify),
+      mSource(source),
       mLooper(new ALooper),
       mParser(new FragmentedMP4Parser),
       mEOS(false) {
diff --git a/media/libmediaplayerservice/nuplayer/mp4/MP4Source.h b/media/libmediaplayerservice/nuplayer/mp4/MP4Source.h
index abca236..b16a111 100644
--- a/media/libmediaplayerservice/nuplayer/mp4/MP4Source.h
+++ b/media/libmediaplayerservice/nuplayer/mp4/MP4Source.h
@@ -24,7 +24,7 @@
 struct FragmentedMP4Parser;
 
 struct MP4Source : public NuPlayer::Source {
-    MP4Source(const sp<IStreamSource> &source);
+    MP4Source(const sp<AMessage> &notify, const sp<IStreamSource> &source);
 
     virtual void start();