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