ALooperRoster.cpp revision 11cc270ac5fd522c9e6491a7933516a96da4f62e
172961230a5890071bcca436eb5630172ce84ec41Andreas Huber/*
272961230a5890071bcca436eb5630172ce84ec41Andreas Huber * Copyright (C) 2010 The Android Open Source Project
372961230a5890071bcca436eb5630172ce84ec41Andreas Huber *
472961230a5890071bcca436eb5630172ce84ec41Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
572961230a5890071bcca436eb5630172ce84ec41Andreas Huber * you may not use this file except in compliance with the License.
672961230a5890071bcca436eb5630172ce84ec41Andreas Huber * You may obtain a copy of the License at
772961230a5890071bcca436eb5630172ce84ec41Andreas Huber *
872961230a5890071bcca436eb5630172ce84ec41Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
972961230a5890071bcca436eb5630172ce84ec41Andreas Huber *
1072961230a5890071bcca436eb5630172ce84ec41Andreas Huber * Unless required by applicable law or agreed to in writing, software
1172961230a5890071bcca436eb5630172ce84ec41Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1272961230a5890071bcca436eb5630172ce84ec41Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1372961230a5890071bcca436eb5630172ce84ec41Andreas Huber * See the License for the specific language governing permissions and
1472961230a5890071bcca436eb5630172ce84ec41Andreas Huber * limitations under the License.
1572961230a5890071bcca436eb5630172ce84ec41Andreas Huber */
1672961230a5890071bcca436eb5630172ce84ec41Andreas Huber
1772961230a5890071bcca436eb5630172ce84ec41Andreas Huber//#define LOG_NDEBUG 0
1872961230a5890071bcca436eb5630172ce84ec41Andreas Huber#define LOG_TAG "ALooperRoster"
1972961230a5890071bcca436eb5630172ce84ec41Andreas Huber#include <utils/Log.h>
2072961230a5890071bcca436eb5630172ce84ec41Andreas Huber
2172961230a5890071bcca436eb5630172ce84ec41Andreas Huber#include "ALooperRoster.h"
2272961230a5890071bcca436eb5630172ce84ec41Andreas Huber
2372961230a5890071bcca436eb5630172ce84ec41Andreas Huber#include "ADebug.h"
2472961230a5890071bcca436eb5630172ce84ec41Andreas Huber#include "AHandler.h"
2572961230a5890071bcca436eb5630172ce84ec41Andreas Huber#include "AMessage.h"
2672961230a5890071bcca436eb5630172ce84ec41Andreas Huber
2772961230a5890071bcca436eb5630172ce84ec41Andreas Hubernamespace android {
2872961230a5890071bcca436eb5630172ce84ec41Andreas Huber
2972961230a5890071bcca436eb5630172ce84ec41Andreas HuberALooperRoster::ALooperRoster()
3072961230a5890071bcca436eb5630172ce84ec41Andreas Huber    : mNextHandlerID(1) {
3172961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
3272961230a5890071bcca436eb5630172ce84ec41Andreas Huber
3372961230a5890071bcca436eb5630172ce84ec41Andreas HuberALooper::handler_id ALooperRoster::registerHandler(
3472961230a5890071bcca436eb5630172ce84ec41Andreas Huber        const sp<ALooper> looper, const sp<AHandler> &handler) {
3572961230a5890071bcca436eb5630172ce84ec41Andreas Huber    Mutex::Autolock autoLock(mLock);
3672961230a5890071bcca436eb5630172ce84ec41Andreas Huber
3772961230a5890071bcca436eb5630172ce84ec41Andreas Huber    if (handler->id() != 0) {
3872961230a5890071bcca436eb5630172ce84ec41Andreas Huber        CHECK(!"A handler must only be registered once.");
3972961230a5890071bcca436eb5630172ce84ec41Andreas Huber        return INVALID_OPERATION;
4072961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
4172961230a5890071bcca436eb5630172ce84ec41Andreas Huber
4272961230a5890071bcca436eb5630172ce84ec41Andreas Huber    HandlerInfo info;
4372961230a5890071bcca436eb5630172ce84ec41Andreas Huber    info.mLooper = looper;
4472961230a5890071bcca436eb5630172ce84ec41Andreas Huber    info.mHandler = handler;
4572961230a5890071bcca436eb5630172ce84ec41Andreas Huber    ALooper::handler_id handlerID = mNextHandlerID++;
4672961230a5890071bcca436eb5630172ce84ec41Andreas Huber    mHandlers.add(handlerID, info);
4772961230a5890071bcca436eb5630172ce84ec41Andreas Huber
4872961230a5890071bcca436eb5630172ce84ec41Andreas Huber    handler->setID(handlerID);
4972961230a5890071bcca436eb5630172ce84ec41Andreas Huber
5072961230a5890071bcca436eb5630172ce84ec41Andreas Huber    return handlerID;
5172961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
5272961230a5890071bcca436eb5630172ce84ec41Andreas Huber
5372961230a5890071bcca436eb5630172ce84ec41Andreas Hubervoid ALooperRoster::unregisterHandler(ALooper::handler_id handlerID) {
5472961230a5890071bcca436eb5630172ce84ec41Andreas Huber    Mutex::Autolock autoLock(mLock);
5572961230a5890071bcca436eb5630172ce84ec41Andreas Huber
5672961230a5890071bcca436eb5630172ce84ec41Andreas Huber    ssize_t index = mHandlers.indexOfKey(handlerID);
5711cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber    CHECK_GE(index, 0);
5872961230a5890071bcca436eb5630172ce84ec41Andreas Huber
5972961230a5890071bcca436eb5630172ce84ec41Andreas Huber    const HandlerInfo &info = mHandlers.valueAt(index);
6011cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber
6111cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber    sp<AHandler> handler = info.mHandler.promote();
6211cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber
6311cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber    if (handler != NULL) {
6411cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber        handler->setID(0);
6511cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber    }
6672961230a5890071bcca436eb5630172ce84ec41Andreas Huber
6772961230a5890071bcca436eb5630172ce84ec41Andreas Huber    mHandlers.removeItemsAt(index);
6872961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
6972961230a5890071bcca436eb5630172ce84ec41Andreas Huber
7072961230a5890071bcca436eb5630172ce84ec41Andreas Hubervoid ALooperRoster::postMessage(
7172961230a5890071bcca436eb5630172ce84ec41Andreas Huber        const sp<AMessage> &msg, int64_t delayUs) {
7272961230a5890071bcca436eb5630172ce84ec41Andreas Huber    Mutex::Autolock autoLock(mLock);
7372961230a5890071bcca436eb5630172ce84ec41Andreas Huber
7472961230a5890071bcca436eb5630172ce84ec41Andreas Huber    ssize_t index = mHandlers.indexOfKey(msg->target());
7572961230a5890071bcca436eb5630172ce84ec41Andreas Huber
7672961230a5890071bcca436eb5630172ce84ec41Andreas Huber    if (index < 0) {
7772961230a5890071bcca436eb5630172ce84ec41Andreas Huber        LOG(WARNING) << "failed to post message. Target handler not registered.";
7872961230a5890071bcca436eb5630172ce84ec41Andreas Huber        return;
7972961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
8072961230a5890071bcca436eb5630172ce84ec41Andreas Huber
8172961230a5890071bcca436eb5630172ce84ec41Andreas Huber    const HandlerInfo &info = mHandlers.valueAt(index);
8211cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber
8311cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber    sp<ALooper> looper = info.mLooper.promote();
8411cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber
8511cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber    if (looper == NULL) {
8611cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber        LOG(WARNING) << "failed to post message. "
8711cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber                        "Target handler still registered, but object gone.";
8811cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber
8911cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber        mHandlers.removeItemsAt(index);
9011cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber        return;
9111cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber    }
9211cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber
9311cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber    looper->post(msg, delayUs);
9472961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
9572961230a5890071bcca436eb5630172ce84ec41Andreas Huber
9672961230a5890071bcca436eb5630172ce84ec41Andreas Hubervoid ALooperRoster::deliverMessage(const sp<AMessage> &msg) {
9772961230a5890071bcca436eb5630172ce84ec41Andreas Huber    sp<AHandler> handler;
9872961230a5890071bcca436eb5630172ce84ec41Andreas Huber
9972961230a5890071bcca436eb5630172ce84ec41Andreas Huber    {
10072961230a5890071bcca436eb5630172ce84ec41Andreas Huber        Mutex::Autolock autoLock(mLock);
10172961230a5890071bcca436eb5630172ce84ec41Andreas Huber
10272961230a5890071bcca436eb5630172ce84ec41Andreas Huber        ssize_t index = mHandlers.indexOfKey(msg->target());
10372961230a5890071bcca436eb5630172ce84ec41Andreas Huber
10472961230a5890071bcca436eb5630172ce84ec41Andreas Huber        if (index < 0) {
10511cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber            LOG(WARNING) << "failed to deliver message. "
10611cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber                         << "Target handler not registered.";
10772961230a5890071bcca436eb5630172ce84ec41Andreas Huber            return;
10872961230a5890071bcca436eb5630172ce84ec41Andreas Huber        }
10972961230a5890071bcca436eb5630172ce84ec41Andreas Huber
11072961230a5890071bcca436eb5630172ce84ec41Andreas Huber        const HandlerInfo &info = mHandlers.valueAt(index);
11111cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber        handler = info.mHandler.promote();
11211cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber
11311cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber        if (handler == NULL) {
11411cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber            LOG(WARNING) << "failed to deliver message. "
11511cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber                            "Target handler registered, but object gone.";
11611cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber
11711cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber            mHandlers.removeItemsAt(index);
11811cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber            return;
11911cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber        }
12072961230a5890071bcca436eb5630172ce84ec41Andreas Huber    }
12172961230a5890071bcca436eb5630172ce84ec41Andreas Huber
12272961230a5890071bcca436eb5630172ce84ec41Andreas Huber    handler->onMessageReceived(msg);
12372961230a5890071bcca436eb5630172ce84ec41Andreas Huber}
12472961230a5890071bcca436eb5630172ce84ec41Andreas Huber
125e2b20987c2652a984d10520ef3542d50d91119c5Andreas Hubersp<ALooper> ALooperRoster::findLooper(ALooper::handler_id handlerID) {
126e2b20987c2652a984d10520ef3542d50d91119c5Andreas Huber    Mutex::Autolock autoLock(mLock);
127e2b20987c2652a984d10520ef3542d50d91119c5Andreas Huber
128e2b20987c2652a984d10520ef3542d50d91119c5Andreas Huber    ssize_t index = mHandlers.indexOfKey(handlerID);
129e2b20987c2652a984d10520ef3542d50d91119c5Andreas Huber
130e2b20987c2652a984d10520ef3542d50d91119c5Andreas Huber    if (index < 0) {
131e2b20987c2652a984d10520ef3542d50d91119c5Andreas Huber        return NULL;
132e2b20987c2652a984d10520ef3542d50d91119c5Andreas Huber    }
133e2b20987c2652a984d10520ef3542d50d91119c5Andreas Huber
13411cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber    sp<ALooper> looper = mHandlers.valueAt(index).mLooper.promote();
13511cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber
13611cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber    if (looper == NULL) {
13711cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber        mHandlers.removeItemsAt(index);
13811cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber        return NULL;
13911cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber    }
14011cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber
14111cc270ac5fd522c9e6491a7933516a96da4f62eAndreas Huber    return looper;
142e2b20987c2652a984d10520ef3542d50d91119c5Andreas Huber}
143e2b20987c2652a984d10520ef3542d50d91119c5Andreas Huber
14472961230a5890071bcca436eb5630172ce84ec41Andreas Huber}  // namespace android
145