michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim:set ts=2 sw=2 sts=2 et cindent: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: //#define LOG_NDEBUG 0 michael@0: #define LOG_TAG "MediaResourceManagerService" michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: #include "MediaResourceManagerClient.h" michael@0: #include "MediaResourceManagerService.h" michael@0: michael@0: namespace android { michael@0: michael@0: /* static */ michael@0: void MediaResourceManagerService::instantiate() { michael@0: defaultServiceManager()->addService( michael@0: String16("media.resource_manager"), new MediaResourceManagerService()); michael@0: } michael@0: michael@0: MediaResourceManagerService::MediaResourceManagerService() michael@0: : mVideoDecoderCount(VIDEO_DECODER_COUNT) michael@0: { michael@0: mLooper = new ALooper; michael@0: mLooper->setName("MediaResourceManagerService"); michael@0: michael@0: mReflector = new AHandlerReflector(this); michael@0: // Register AMessage handler to ALooper. michael@0: mLooper->registerHandler(mReflector); michael@0: // Start ALooper thread. michael@0: mLooper->start(); michael@0: } michael@0: michael@0: MediaResourceManagerService::~MediaResourceManagerService() michael@0: { michael@0: // Unregister AMessage handler from ALooper. michael@0: mLooper->unregisterHandler(mReflector->id()); michael@0: // Stop ALooper thread. michael@0: mLooper->stop(); michael@0: } michael@0: michael@0: void MediaResourceManagerService::binderDied(const wp& who) michael@0: { michael@0: if (who != NULL) { michael@0: Mutex::Autolock autoLock(mLock); michael@0: sp binder = who.promote(); michael@0: if (binder != NULL) { michael@0: cancelClientLocked(binder); michael@0: } michael@0: } michael@0: } michael@0: michael@0: void MediaResourceManagerService::requestMediaResource(const sp& client, int resourceType) michael@0: { michael@0: if (resourceType != MediaResourceManagerClient::HW_VIDEO_DECODER) { michael@0: // Support only HW_VIDEO_DECODER michael@0: return; michael@0: } michael@0: michael@0: { michael@0: Mutex::Autolock autoLock(mLock); michael@0: sp binder = client->asBinder(); michael@0: mVideoCodecRequestQueue.push_back(binder); michael@0: binder->linkToDeath(this); michael@0: } michael@0: michael@0: sp notify = michael@0: new AMessage(kNotifyRequest, mReflector->id()); michael@0: // Post AMessage to MediaResourceManagerService via ALooper. michael@0: notify->post(); michael@0: } michael@0: michael@0: status_t MediaResourceManagerService::cancelClient(const sp& client) michael@0: { michael@0: { michael@0: Mutex::Autolock autoLock(mLock); michael@0: sp binder = client->asBinder(); michael@0: cancelClientLocked(binder); michael@0: } michael@0: michael@0: sp notify = michael@0: new AMessage(kNotifyRequest, mReflector->id()); michael@0: // Post AMessage to MediaResourceManagerService via ALooper. michael@0: notify->post(); michael@0: michael@0: return NO_ERROR; michael@0: } michael@0: michael@0: // Called on ALooper thread. michael@0: void MediaResourceManagerService::onMessageReceived(const sp &msg) michael@0: { michael@0: Mutex::Autolock autoLock(mLock); michael@0: michael@0: // Exit if no request. michael@0: if (mVideoCodecRequestQueue.empty()) { michael@0: return; michael@0: } michael@0: michael@0: // Check if resource is available michael@0: int found = -1; michael@0: for (int i=0 ; i client = interface_cast(mVideoDecoderSlots[found].mClient); michael@0: client->statusChanged(MediaResourceManagerClient::CLIENT_STATE_RESOURCE_ASSIGNED); michael@0: } michael@0: michael@0: void MediaResourceManagerService::cancelClientLocked(const sp& binder) michael@0: { michael@0: // Clear the request from request queue. michael@0: Fifo::iterator it(mVideoCodecRequestQueue.begin()); michael@0: while (it != mVideoCodecRequestQueue.end()) { michael@0: if ((*it).get() == binder.get()) { michael@0: mVideoCodecRequestQueue.erase(it); michael@0: break; michael@0: } michael@0: it++; michael@0: } michael@0: michael@0: // Clear the client from the resource michael@0: for (int i=0 ; iunlinkToDeath(this); michael@0: } michael@0: michael@0: }; // namespace android michael@0: