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