diff options
author | Andreas Huber <andih@google.com> | 2011-08-26 13:47:26 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-08-26 13:47:26 -0700 |
commit | 539340fe2c3dfd33564c1ddc9ee5c2884aa56874 (patch) | |
tree | a45a6b702449ba71b59315c20e80cc07979ac773 | |
parent | dae908a391222710d26692ee5fcf307fd96197a2 (diff) | |
parent | e688257456c315cbd2d5fd4f32bd52eac0b98195 (diff) | |
download | frameworks_base-539340fe2c3dfd33564c1ddc9ee5c2884aa56874.zip frameworks_base-539340fe2c3dfd33564c1ddc9ee5c2884aa56874.tar.gz frameworks_base-539340fe2c3dfd33564c1ddc9ee5c2884aa56874.tar.bz2 |
Merge "Support for posting messages and synchronously waiting for a response."
-rw-r--r-- | include/media/stagefright/foundation/ALooperRoster.h | 13 | ||||
-rw-r--r-- | include/media/stagefright/foundation/AMessage.h | 11 | ||||
-rw-r--r-- | media/libstagefright/foundation/ALooperRoster.cpp | 49 | ||||
-rw-r--r-- | media/libstagefright/foundation/AMessage.cpp | 25 |
4 files changed, 91 insertions, 7 deletions
diff --git a/include/media/stagefright/foundation/ALooperRoster.h b/include/media/stagefright/foundation/ALooperRoster.h index c1bd4ed..2e5fd73 100644 --- a/include/media/stagefright/foundation/ALooperRoster.h +++ b/include/media/stagefright/foundation/ALooperRoster.h @@ -31,9 +31,14 @@ struct ALooperRoster { void unregisterHandler(ALooper::handler_id handlerID); - void postMessage(const sp<AMessage> &msg, int64_t delayUs = 0); + status_t postMessage(const sp<AMessage> &msg, int64_t delayUs = 0); void deliverMessage(const sp<AMessage> &msg); + status_t postAndAwaitResponse( + const sp<AMessage> &msg, sp<AMessage> *response); + + void postReply(uint32_t replyID, const sp<AMessage> &reply); + sp<ALooper> findLooper(ALooper::handler_id handlerID); private: @@ -45,6 +50,12 @@ private: Mutex mLock; KeyedVector<ALooper::handler_id, HandlerInfo> mHandlers; ALooper::handler_id mNextHandlerID; + uint32_t mNextReplyID; + Condition mRepliesCondition; + + KeyedVector<uint32_t, sp<AMessage> > mReplies; + + status_t postMessage_l(const sp<AMessage> &msg, int64_t delayUs); DISALLOW_EVIL_CONSTRUCTORS(ALooperRoster); }; diff --git a/include/media/stagefright/foundation/AMessage.h b/include/media/stagefright/foundation/AMessage.h index 72dc730..7ec54aa 100644 --- a/include/media/stagefright/foundation/AMessage.h +++ b/include/media/stagefright/foundation/AMessage.h @@ -72,6 +72,17 @@ struct AMessage : public RefBase { void post(int64_t delayUs = 0); + // Posts the message to its target and waits for a response (or error) + // before returning. + status_t postAndAwaitResponse(sp<AMessage> *response); + + // If this returns true, the sender of this message is synchronously + // awaiting a response, the "replyID" can be used to send the response + // via "postReply" below. + bool senderAwaitsResponse(uint32_t *replyID) const; + + void postReply(uint32_t replyID); + // Performs a deep-copy of "this", contained messages are in turn "dup'ed". // Warning: RefBase items, i.e. "objects" are _not_ copied but only have // their refcount incremented. diff --git a/media/libstagefright/foundation/ALooperRoster.cpp b/media/libstagefright/foundation/ALooperRoster.cpp index 8aa1b15..e399f2f 100644 --- a/media/libstagefright/foundation/ALooperRoster.cpp +++ b/media/libstagefright/foundation/ALooperRoster.cpp @@ -27,7 +27,8 @@ namespace android { ALooperRoster::ALooperRoster() - : mNextHandlerID(1) { + : mNextHandlerID(1), + mNextReplyID(1) { } ALooper::handler_id ALooperRoster::registerHandler( @@ -70,15 +71,19 @@ void ALooperRoster::unregisterHandler(ALooper::handler_id handlerID) { mHandlers.removeItemsAt(index); } -void ALooperRoster::postMessage( +status_t ALooperRoster::postMessage( const sp<AMessage> &msg, int64_t delayUs) { Mutex::Autolock autoLock(mLock); + return postMessage_l(msg, delayUs); +} +status_t ALooperRoster::postMessage_l( + const sp<AMessage> &msg, int64_t delayUs) { ssize_t index = mHandlers.indexOfKey(msg->target()); if (index < 0) { LOGW("failed to post message. Target handler not registered."); - return; + return -ENOENT; } const HandlerInfo &info = mHandlers.valueAt(index); @@ -91,10 +96,12 @@ void ALooperRoster::postMessage( msg->target()); mHandlers.removeItemsAt(index); - return; + return -ENOENT; } looper->post(msg, delayUs); + + return OK; } void ALooperRoster::deliverMessage(const sp<AMessage> &msg) { @@ -145,4 +152,38 @@ sp<ALooper> ALooperRoster::findLooper(ALooper::handler_id handlerID) { return looper; } +status_t ALooperRoster::postAndAwaitResponse( + const sp<AMessage> &msg, sp<AMessage> *response) { + Mutex::Autolock autoLock(mLock); + + uint32_t replyID = mNextReplyID++; + + msg->setInt32("replyID", replyID); + + status_t err = postMessage_l(msg, 0 /* delayUs */); + + if (err != OK) { + response->clear(); + return err; + } + + ssize_t index; + while ((index = mReplies.indexOfKey(replyID)) < 0) { + mRepliesCondition.wait(mLock); + } + + *response = mReplies.valueAt(index); + mReplies.removeItemsAt(index); + + return OK; +} + +void ALooperRoster::postReply(uint32_t replyID, const sp<AMessage> &reply) { + Mutex::Autolock autoLock(mLock); + + CHECK(mReplies.indexOfKey(replyID) < 0); + mReplies.add(replyID, reply); + mRepliesCondition.broadcast(); +} + } // namespace android diff --git a/media/libstagefright/foundation/AMessage.cpp b/media/libstagefright/foundation/AMessage.cpp index b592c3f..582bdba 100644 --- a/media/libstagefright/foundation/AMessage.cpp +++ b/media/libstagefright/foundation/AMessage.cpp @@ -27,6 +27,8 @@ namespace android { +extern ALooperRoster gLooperRoster; + AMessage::AMessage(uint32_t what, ALooper::handler_id target) : mWhat(what), mTarget(target), @@ -227,11 +229,30 @@ bool AMessage::findRect( } void AMessage::post(int64_t delayUs) { - extern ALooperRoster gLooperRoster; - gLooperRoster.postMessage(this, delayUs); } +status_t AMessage::postAndAwaitResponse(sp<AMessage> *response) { + return gLooperRoster.postAndAwaitResponse(this, response); +} + +void AMessage::postReply(uint32_t replyID) { + gLooperRoster.postReply(replyID, this); +} + +bool AMessage::senderAwaitsResponse(uint32_t *replyID) const { + int32_t tmp; + bool found = findInt32("replyID", &tmp); + + if (!found) { + return false; + } + + *replyID = static_cast<uint32_t>(tmp); + + return true; +} + sp<AMessage> AMessage::dup() const { sp<AMessage> msg = new AMessage(mWhat, mTarget); msg->mNumItems = mNumItems; |