17d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber/* 27d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * Copyright (C) 2010 The Android Open Source Project 37d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * 47d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 57d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * you may not use this file except in compliance with the License. 67d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * You may obtain a copy of the License at 77d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * 87d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 97d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * 107d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * Unless required by applicable law or agreed to in writing, software 117d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 127d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * See the License for the specific language governing permissions and 147d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber * limitations under the License. 157d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber */ 167d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 177d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber//#define LOG_NDEBUG 0 187d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber#define LOG_TAG "ALooperRoster" 197d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber#include <utils/Log.h> 207d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 217d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber#include "ALooperRoster.h" 227d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 237d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber#include "ADebug.h" 247d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber#include "AHandler.h" 257d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber#include "AMessage.h" 267d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 277d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Hubernamespace android { 287d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 297d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas HuberALooperRoster::ALooperRoster() 30e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber : mNextHandlerID(1), 31e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber mNextReplyID(1) { 327d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber} 337d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 347d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas HuberALooper::handler_id ALooperRoster::registerHandler( 357d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber const sp<ALooper> looper, const sp<AHandler> &handler) { 367d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber Mutex::Autolock autoLock(mLock); 377d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 387d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber if (handler->id() != 0) { 397d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber CHECK(!"A handler must only be registered once."); 407d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber return INVALID_OPERATION; 417d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 427d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 437d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber HandlerInfo info; 447d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber info.mLooper = looper; 457d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber info.mHandler = handler; 467d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber ALooper::handler_id handlerID = mNextHandlerID++; 477d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber mHandlers.add(handlerID, info); 487d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 497d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber handler->setID(handlerID); 507d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 517d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber return handlerID; 527d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber} 537d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 547d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Hubervoid ALooperRoster::unregisterHandler(ALooper::handler_id handlerID) { 557d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber Mutex::Autolock autoLock(mLock); 567d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 577d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber ssize_t index = mHandlers.indexOfKey(handlerID); 58d68cda472a3646966a203338ccac04f0783293b7Andreas Huber 59d68cda472a3646966a203338ccac04f0783293b7Andreas Huber if (index < 0) { 60d68cda472a3646966a203338ccac04f0783293b7Andreas Huber return; 61d68cda472a3646966a203338ccac04f0783293b7Andreas Huber } 627d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 637d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber const HandlerInfo &info = mHandlers.valueAt(index); 6457576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber 6557576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber sp<AHandler> handler = info.mHandler.promote(); 6657576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber 6757576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber if (handler != NULL) { 6857576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber handler->setID(0); 6957576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber } 707d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 717d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber mHandlers.removeItemsAt(index); 727d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber} 737d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 74e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huberstatus_t ALooperRoster::postMessage( 757d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber const sp<AMessage> &msg, int64_t delayUs) { 767d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber Mutex::Autolock autoLock(mLock); 77e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber return postMessage_l(msg, delayUs); 78e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber} 797d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 80e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huberstatus_t ALooperRoster::postMessage_l( 81e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber const sp<AMessage> &msg, int64_t delayUs) { 827d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber ssize_t index = mHandlers.indexOfKey(msg->target()); 837d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 847d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber if (index < 0) { 856e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber LOGW("failed to post message. Target handler not registered."); 86e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber return -ENOENT; 877d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 887d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 897d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber const HandlerInfo &info = mHandlers.valueAt(index); 9057576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber 9157576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber sp<ALooper> looper = info.mLooper.promote(); 9257576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber 9357576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber if (looper == NULL) { 946e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber LOGW("failed to post message. " 95d68cda472a3646966a203338ccac04f0783293b7Andreas Huber "Target handler %d still registered, but object gone.", 96d68cda472a3646966a203338ccac04f0783293b7Andreas Huber msg->target()); 9757576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber 9857576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber mHandlers.removeItemsAt(index); 99e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber return -ENOENT; 10057576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber } 10157576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber 10257576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber looper->post(msg, delayUs); 103e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber 104e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber return OK; 1057d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber} 1067d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1077d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Hubervoid ALooperRoster::deliverMessage(const sp<AMessage> &msg) { 1087d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber sp<AHandler> handler; 1097d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1107d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber { 1117d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber Mutex::Autolock autoLock(mLock); 1127d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1137d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber ssize_t index = mHandlers.indexOfKey(msg->target()); 1147d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1157d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber if (index < 0) { 1166e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber LOGW("failed to deliver message. Target handler not registered."); 1177d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber return; 1187d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 1197d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1207d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber const HandlerInfo &info = mHandlers.valueAt(index); 12157576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber handler = info.mHandler.promote(); 12257576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber 12357576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber if (handler == NULL) { 1246e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber LOGW("failed to deliver message. " 125d68cda472a3646966a203338ccac04f0783293b7Andreas Huber "Target handler %d registered, but object gone.", 126d68cda472a3646966a203338ccac04f0783293b7Andreas Huber msg->target()); 12757576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber 12857576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber mHandlers.removeItemsAt(index); 12957576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber return; 13057576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber } 1317d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 1327d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1337d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber handler->onMessageReceived(msg); 1347d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber} 1357d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 136058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Hubersp<ALooper> ALooperRoster::findLooper(ALooper::handler_id handlerID) { 137058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber Mutex::Autolock autoLock(mLock); 138058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber 139058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber ssize_t index = mHandlers.indexOfKey(handlerID); 140058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber 141058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber if (index < 0) { 142058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber return NULL; 143058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber } 144058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber 14557576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber sp<ALooper> looper = mHandlers.valueAt(index).mLooper.promote(); 14657576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber 14757576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber if (looper == NULL) { 14857576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber mHandlers.removeItemsAt(index); 14957576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber return NULL; 15057576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber } 15157576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber 15257576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber return looper; 153058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber} 154058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber 155e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huberstatus_t ALooperRoster::postAndAwaitResponse( 156e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber const sp<AMessage> &msg, sp<AMessage> *response) { 157e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber Mutex::Autolock autoLock(mLock); 158e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber 159e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber uint32_t replyID = mNextReplyID++; 160e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber 161e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber msg->setInt32("replyID", replyID); 162e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber 163e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber status_t err = postMessage_l(msg, 0 /* delayUs */); 164e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber 165e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber if (err != OK) { 166e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber response->clear(); 167e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber return err; 168e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber } 169e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber 170e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber ssize_t index; 171e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber while ((index = mReplies.indexOfKey(replyID)) < 0) { 172e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber mRepliesCondition.wait(mLock); 173e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber } 174e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber 175e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber *response = mReplies.valueAt(index); 176e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber mReplies.removeItemsAt(index); 177e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber 178e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber return OK; 179e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber} 180e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber 181e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Hubervoid ALooperRoster::postReply(uint32_t replyID, const sp<AMessage> &reply) { 182e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber Mutex::Autolock autoLock(mLock); 183e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber 184e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber CHECK(mReplies.indexOfKey(replyID) < 0); 185e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber mReplies.add(replyID, reply); 186e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber mRepliesCondition.broadcast(); 187e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber} 188e688257456c315cbd2d5fd4f32bd52eac0b98195Andreas Huber 1897d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber} // namespace android 190