ALooperRoster.cpp revision d68cda472a3646966a203338ccac04f0783293b7
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() 307d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber : mNextHandlerID(1) { 317d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber} 327d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 337d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas HuberALooper::handler_id ALooperRoster::registerHandler( 347d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber const sp<ALooper> looper, const sp<AHandler> &handler) { 357d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber Mutex::Autolock autoLock(mLock); 367d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 377d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber if (handler->id() != 0) { 387d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber CHECK(!"A handler must only be registered once."); 397d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber return INVALID_OPERATION; 407d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 417d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 427d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber HandlerInfo info; 437d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber info.mLooper = looper; 447d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber info.mHandler = handler; 457d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber ALooper::handler_id handlerID = mNextHandlerID++; 467d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber mHandlers.add(handlerID, info); 477d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 487d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber handler->setID(handlerID); 497d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 507d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber return handlerID; 517d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber} 527d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 537d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Hubervoid ALooperRoster::unregisterHandler(ALooper::handler_id handlerID) { 547d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber Mutex::Autolock autoLock(mLock); 557d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 567d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber ssize_t index = mHandlers.indexOfKey(handlerID); 57d68cda472a3646966a203338ccac04f0783293b7Andreas Huber 58d68cda472a3646966a203338ccac04f0783293b7Andreas Huber if (index < 0) { 59d68cda472a3646966a203338ccac04f0783293b7Andreas Huber return; 60d68cda472a3646966a203338ccac04f0783293b7Andreas Huber } 617d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 627d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber const HandlerInfo &info = mHandlers.valueAt(index); 6357576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber 6457576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber sp<AHandler> handler = info.mHandler.promote(); 6557576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber 6657576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber if (handler != NULL) { 6757576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber handler->setID(0); 6857576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber } 697d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 707d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber mHandlers.removeItemsAt(index); 717d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber} 727d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 737d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Hubervoid ALooperRoster::postMessage( 747d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber const sp<AMessage> &msg, int64_t delayUs) { 757d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber Mutex::Autolock autoLock(mLock); 767d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 777d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber ssize_t index = mHandlers.indexOfKey(msg->target()); 787d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 797d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber if (index < 0) { 806e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber LOGW("failed to post message. Target handler not registered."); 817d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber return; 827d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 837d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 847d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber const HandlerInfo &info = mHandlers.valueAt(index); 8557576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber 8657576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber sp<ALooper> looper = info.mLooper.promote(); 8757576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber 8857576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber if (looper == NULL) { 896e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber LOGW("failed to post message. " 90d68cda472a3646966a203338ccac04f0783293b7Andreas Huber "Target handler %d still registered, but object gone.", 91d68cda472a3646966a203338ccac04f0783293b7Andreas Huber msg->target()); 9257576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber 9357576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber mHandlers.removeItemsAt(index); 9457576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber return; 9557576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber } 9657576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber 9757576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber looper->post(msg, delayUs); 987d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber} 997d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1007d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Hubervoid ALooperRoster::deliverMessage(const sp<AMessage> &msg) { 1017d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber sp<AHandler> handler; 1027d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1037d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber { 1047d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber Mutex::Autolock autoLock(mLock); 1057d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1067d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber ssize_t index = mHandlers.indexOfKey(msg->target()); 1077d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1087d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber if (index < 0) { 1096e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber LOGW("failed to deliver message. Target handler not registered."); 1107d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber return; 1117d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 1127d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1137d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber const HandlerInfo &info = mHandlers.valueAt(index); 11457576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber handler = info.mHandler.promote(); 11557576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber 11657576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber if (handler == NULL) { 1176e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber LOGW("failed to deliver message. " 118d68cda472a3646966a203338ccac04f0783293b7Andreas Huber "Target handler %d registered, but object gone.", 119d68cda472a3646966a203338ccac04f0783293b7Andreas Huber msg->target()); 12057576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber 12157576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber mHandlers.removeItemsAt(index); 12257576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber return; 12357576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber } 1247d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber } 1257d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 1267d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber handler->onMessageReceived(msg); 1277d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber} 1287d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber 129058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Hubersp<ALooper> ALooperRoster::findLooper(ALooper::handler_id handlerID) { 130058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber Mutex::Autolock autoLock(mLock); 131058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber 132058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber ssize_t index = mHandlers.indexOfKey(handlerID); 133058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber 134058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber if (index < 0) { 135058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber return NULL; 136058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber } 137058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber 13857576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber sp<ALooper> looper = mHandlers.valueAt(index).mLooper.promote(); 13957576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber 14057576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber if (looper == NULL) { 14157576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber mHandlers.removeItemsAt(index); 14257576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber return NULL; 14357576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber } 14457576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber 14557576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber return looper; 146058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber} 147058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber 1487d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber} // namespace android 149