ALooperRoster.cpp revision 6e3fa444c5b3970666707bb2b6d25e2615dafe80
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);
5757576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber    CHECK_GE(index, 0);
587d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber
597d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber    const HandlerInfo &info = mHandlers.valueAt(index);
6057576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber
6157576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber    sp<AHandler> handler = info.mHandler.promote();
6257576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber
6357576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber    if (handler != NULL) {
6457576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber        handler->setID(0);
6557576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber    }
667d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber
677d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber    mHandlers.removeItemsAt(index);
687d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber}
697d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber
707d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Hubervoid ALooperRoster::postMessage(
717d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber        const sp<AMessage> &msg, int64_t delayUs) {
727d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber    Mutex::Autolock autoLock(mLock);
737d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber
747d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber    ssize_t index = mHandlers.indexOfKey(msg->target());
757d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber
767d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber    if (index < 0) {
776e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber        LOGW("failed to post message. Target handler not registered.");
787d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber        return;
797d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber    }
807d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber
817d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber    const HandlerInfo &info = mHandlers.valueAt(index);
8257576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber
8357576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber    sp<ALooper> looper = info.mLooper.promote();
8457576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber
8557576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber    if (looper == NULL) {
866e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber        LOGW("failed to post message. "
876e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber             "Target handler still registered, but object gone.");
8857576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber
8957576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber        mHandlers.removeItemsAt(index);
9057576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber        return;
9157576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber    }
9257576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber
9357576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber    looper->post(msg, delayUs);
947d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber}
957d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber
967d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Hubervoid ALooperRoster::deliverMessage(const sp<AMessage> &msg) {
977d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber    sp<AHandler> handler;
987d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber
997d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber    {
1007d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber        Mutex::Autolock autoLock(mLock);
1017d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber
1027d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber        ssize_t index = mHandlers.indexOfKey(msg->target());
1037d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber
1047d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber        if (index < 0) {
1056e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber            LOGW("failed to deliver message. Target handler not registered.");
1067d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber            return;
1077d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber        }
1087d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber
1097d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber        const HandlerInfo &info = mHandlers.valueAt(index);
11057576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber        handler = info.mHandler.promote();
11157576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber
11257576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber        if (handler == NULL) {
1136e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber            LOGW("failed to deliver message. "
1146e3fa444c5b3970666707bb2b6d25e2615dafe80Andreas Huber                 "Target handler registered, but object gone.");
11557576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber
11657576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber            mHandlers.removeItemsAt(index);
11757576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber            return;
11857576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber        }
1197d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber    }
1207d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber
1217d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber    handler->onMessageReceived(msg);
1227d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber}
1237d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber
124058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Hubersp<ALooper> ALooperRoster::findLooper(ALooper::handler_id handlerID) {
125058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber    Mutex::Autolock autoLock(mLock);
126058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber
127058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber    ssize_t index = mHandlers.indexOfKey(handlerID);
128058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber
129058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber    if (index < 0) {
130058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber        return NULL;
131058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber    }
132058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber
13357576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber    sp<ALooper> looper = mHandlers.valueAt(index).mLooper.promote();
13457576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber
13557576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber    if (looper == NULL) {
13657576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber        mHandlers.removeItemsAt(index);
13757576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber        return NULL;
13857576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber    }
13957576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber
14057576c1cae63bebfa7ed880ab510e06f312586eeAndreas Huber    return looper;
141058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber}
142058319eb73aa1d5c3b3b4b79316198e7a49484f1Andreas Huber
1437d2f703649e270b635018f8b7219bb0e1d62a2e5Andreas Huber}  // namespace android
144