Home | History | Annotate | Download | only in foundation
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 //#define LOG_NDEBUG 0
     18 #define LOG_TAG "ALooperRoster"
     19 #include <utils/Log.h>
     20 
     21 #include "ALooperRoster.h"
     22 
     23 #include "ADebug.h"
     24 #include "AHandler.h"
     25 #include "AMessage.h"
     26 
     27 namespace android {
     28 
     29 ALooperRoster::ALooperRoster()
     30     : mNextHandlerID(1) {
     31 }
     32 
     33 ALooper::handler_id ALooperRoster::registerHandler(
     34         const sp<ALooper> looper, const sp<AHandler> &handler) {
     35     Mutex::Autolock autoLock(mLock);
     36 
     37     if (handler->id() != 0) {
     38         CHECK(!"A handler must only be registered once.");
     39         return INVALID_OPERATION;
     40     }
     41 
     42     HandlerInfo info;
     43     info.mLooper = looper;
     44     info.mHandler = handler;
     45     ALooper::handler_id handlerID = mNextHandlerID++;
     46     mHandlers.add(handlerID, info);
     47 
     48     handler->setID(handlerID);
     49 
     50     return handlerID;
     51 }
     52 
     53 void ALooperRoster::unregisterHandler(ALooper::handler_id handlerID) {
     54     Mutex::Autolock autoLock(mLock);
     55 
     56     ssize_t index = mHandlers.indexOfKey(handlerID);
     57 
     58     if (index < 0) {
     59         return;
     60     }
     61 
     62     const HandlerInfo &info = mHandlers.valueAt(index);
     63 
     64     sp<AHandler> handler = info.mHandler.promote();
     65 
     66     if (handler != NULL) {
     67         handler->setID(0);
     68     }
     69 
     70     mHandlers.removeItemsAt(index);
     71 }
     72 
     73 void ALooperRoster::postMessage(
     74         const sp<AMessage> &msg, int64_t delayUs) {
     75     Mutex::Autolock autoLock(mLock);
     76 
     77     ssize_t index = mHandlers.indexOfKey(msg->target());
     78 
     79     if (index < 0) {
     80         LOGW("failed to post message. Target handler not registered.");
     81         return;
     82     }
     83 
     84     const HandlerInfo &info = mHandlers.valueAt(index);
     85 
     86     sp<ALooper> looper = info.mLooper.promote();
     87 
     88     if (looper == NULL) {
     89         LOGW("failed to post message. "
     90              "Target handler %d still registered, but object gone.",
     91              msg->target());
     92 
     93         mHandlers.removeItemsAt(index);
     94         return;
     95     }
     96 
     97     looper->post(msg, delayUs);
     98 }
     99 
    100 void ALooperRoster::deliverMessage(const sp<AMessage> &msg) {
    101     sp<AHandler> handler;
    102 
    103     {
    104         Mutex::Autolock autoLock(mLock);
    105 
    106         ssize_t index = mHandlers.indexOfKey(msg->target());
    107 
    108         if (index < 0) {
    109             LOGW("failed to deliver message. Target handler not registered.");
    110             return;
    111         }
    112 
    113         const HandlerInfo &info = mHandlers.valueAt(index);
    114         handler = info.mHandler.promote();
    115 
    116         if (handler == NULL) {
    117             LOGW("failed to deliver message. "
    118                  "Target handler %d registered, but object gone.",
    119                  msg->target());
    120 
    121             mHandlers.removeItemsAt(index);
    122             return;
    123         }
    124     }
    125 
    126     handler->onMessageReceived(msg);
    127 }
    128 
    129 sp<ALooper> ALooperRoster::findLooper(ALooper::handler_id handlerID) {
    130     Mutex::Autolock autoLock(mLock);
    131 
    132     ssize_t index = mHandlers.indexOfKey(handlerID);
    133 
    134     if (index < 0) {
    135         return NULL;
    136     }
    137 
    138     sp<ALooper> looper = mHandlers.valueAt(index).mLooper.promote();
    139 
    140     if (looper == NULL) {
    141         mHandlers.removeItemsAt(index);
    142         return NULL;
    143     }
    144 
    145     return looper;
    146 }
    147 
    148 }  // namespace android
    149