|  | /* | 
|  | * Copyright 2015, The Android Open Source Project | 
|  | * | 
|  | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | * you may not use this file except in compliance with the License. | 
|  | * You may obtain a copy of the License at | 
|  | * | 
|  | *     http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, software | 
|  | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | * See the License for the specific language governing permissions and | 
|  | * limitations under the License. | 
|  | */ | 
|  |  | 
|  | #define LOG_TAG "BatteryNotifier" | 
|  | //#define LOG_NDEBUG 0 | 
|  |  | 
|  | #include "include/mediautils/BatteryNotifier.h" | 
|  |  | 
|  | #include <binder/IServiceManager.h> | 
|  | #include <utils/Log.h> | 
|  | #include <private/android_filesystem_config.h> | 
|  |  | 
|  | namespace android { | 
|  |  | 
|  | void BatteryNotifier::DeathNotifier::binderDied(const wp<IBinder>& /*who*/) { | 
|  | BatteryNotifier::getInstance().onBatteryStatServiceDied(); | 
|  | } | 
|  |  | 
|  | BatteryNotifier::BatteryNotifier() {} | 
|  |  | 
|  | BatteryNotifier::~BatteryNotifier() { | 
|  | Mutex::Autolock _l(mLock); | 
|  | if (mDeathNotifier != nullptr) { | 
|  | IInterface::asBinder(mBatteryStatService)->unlinkToDeath(mDeathNotifier); | 
|  | } | 
|  | } | 
|  |  | 
|  | void BatteryNotifier::noteStartVideo(uid_t uid) { | 
|  | Mutex::Autolock _l(mLock); | 
|  | sp<IBatteryStats> batteryService = getBatteryService_l(); | 
|  | if (mVideoRefCounts[uid] == 0 && batteryService != nullptr) { | 
|  | batteryService->noteStartVideo(uid); | 
|  | } | 
|  | mVideoRefCounts[uid]++; | 
|  | } | 
|  |  | 
|  | void BatteryNotifier::noteStopVideo(uid_t uid) { | 
|  | Mutex::Autolock _l(mLock); | 
|  | if (mVideoRefCounts.find(uid) == mVideoRefCounts.end()) { | 
|  | ALOGW("%s: video refcount is broken for uid(%d).", __FUNCTION__, (int)uid); | 
|  | return; | 
|  | } | 
|  |  | 
|  | sp<IBatteryStats> batteryService = getBatteryService_l(); | 
|  |  | 
|  | mVideoRefCounts[uid]--; | 
|  | if (mVideoRefCounts[uid] == 0) { | 
|  | if (batteryService != nullptr) { | 
|  | batteryService->noteStopVideo(uid); | 
|  | } | 
|  | mVideoRefCounts.erase(uid); | 
|  | } | 
|  | } | 
|  |  | 
|  | void BatteryNotifier::noteResetVideo() { | 
|  | Mutex::Autolock _l(mLock); | 
|  | sp<IBatteryStats> batteryService = getBatteryService_l(); | 
|  | mVideoRefCounts.clear(); | 
|  | if (batteryService != nullptr) { | 
|  | batteryService->noteResetVideo(); | 
|  | } | 
|  | } | 
|  |  | 
|  | void BatteryNotifier::noteStartAudio(uid_t uid) { | 
|  | Mutex::Autolock _l(mLock); | 
|  | sp<IBatteryStats> batteryService = getBatteryService_l(); | 
|  | if (mAudioRefCounts[uid] == 0 && batteryService != nullptr) { | 
|  | batteryService->noteStartAudio(uid); | 
|  | } | 
|  | mAudioRefCounts[uid]++; | 
|  | } | 
|  |  | 
|  | void BatteryNotifier::noteStopAudio(uid_t uid) { | 
|  | Mutex::Autolock _l(mLock); | 
|  | if (mAudioRefCounts.find(uid) == mAudioRefCounts.end() || (mAudioRefCounts[uid] == 0)) { | 
|  | ALOGE("%s: audio refcount is broken for uid(%d).", __FUNCTION__, (int)uid); | 
|  | return; | 
|  | } | 
|  |  | 
|  | sp<IBatteryStats> batteryService = getBatteryService_l(); | 
|  |  | 
|  | mAudioRefCounts[uid]--; | 
|  | if (mAudioRefCounts[uid] == 0) { | 
|  | if (batteryService != nullptr) { | 
|  | batteryService->noteStopAudio(uid); | 
|  | } | 
|  | mAudioRefCounts.erase(uid); | 
|  | } | 
|  | } | 
|  |  | 
|  | void BatteryNotifier::noteResetAudio() { | 
|  | Mutex::Autolock _l(mLock); | 
|  | sp<IBatteryStats> batteryService = getBatteryService_l(); | 
|  | mAudioRefCounts.clear(); | 
|  | if (batteryService != nullptr) { | 
|  | batteryService->noteResetAudio(); | 
|  | } | 
|  | } | 
|  |  | 
|  | void BatteryNotifier::noteFlashlightOn(const String8& id, uid_t uid) { | 
|  | Mutex::Autolock _l(mLock); | 
|  | sp<IBatteryStats> batteryService = getBatteryService_l(); | 
|  |  | 
|  | std::pair<String8, uid_t> k = std::make_pair(id, uid); | 
|  | if (!mFlashlightState[k]) { | 
|  | mFlashlightState[k] = true; | 
|  | if (batteryService != nullptr) { | 
|  | batteryService->noteFlashlightOn(uid); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void BatteryNotifier::noteFlashlightOff(const String8& id, uid_t uid) { | 
|  | Mutex::Autolock _l(mLock); | 
|  | sp<IBatteryStats> batteryService = getBatteryService_l(); | 
|  |  | 
|  | std::pair<String8, uid_t> k = std::make_pair(id, uid); | 
|  | if (mFlashlightState[k]) { | 
|  | mFlashlightState[k] = false; | 
|  | if (batteryService != nullptr) { | 
|  | batteryService->noteFlashlightOff(uid); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void BatteryNotifier::noteResetFlashlight() { | 
|  | Mutex::Autolock _l(mLock); | 
|  | sp<IBatteryStats> batteryService = getBatteryService_l(); | 
|  | mFlashlightState.clear(); | 
|  | if (batteryService != nullptr) { | 
|  | batteryService->noteResetFlashlight(); | 
|  | } | 
|  | } | 
|  |  | 
|  | void BatteryNotifier::noteStartCamera(const String8& id, uid_t uid) { | 
|  | Mutex::Autolock _l(mLock); | 
|  | sp<IBatteryStats> batteryService = getBatteryService_l(); | 
|  | std::pair<String8, uid_t> k = std::make_pair(id, uid); | 
|  | if (!mCameraState[k]) { | 
|  | mCameraState[k] = true; | 
|  | if (batteryService != nullptr) { | 
|  | batteryService->noteStartCamera(uid); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void BatteryNotifier::noteStopCamera(const String8& id, uid_t uid) { | 
|  | Mutex::Autolock _l(mLock); | 
|  | sp<IBatteryStats> batteryService = getBatteryService_l(); | 
|  | std::pair<String8, uid_t> k = std::make_pair(id, uid); | 
|  | if (mCameraState[k]) { | 
|  | mCameraState[k] = false; | 
|  | if (batteryService != nullptr) { | 
|  | batteryService->noteStopCamera(uid); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void BatteryNotifier::noteResetCamera() { | 
|  | Mutex::Autolock _l(mLock); | 
|  | sp<IBatteryStats> batteryService = getBatteryService_l(); | 
|  | mCameraState.clear(); | 
|  | if (batteryService != nullptr) { | 
|  | batteryService->noteResetCamera(); | 
|  | } | 
|  | } | 
|  |  | 
|  | void BatteryNotifier::onBatteryStatServiceDied() { | 
|  | Mutex::Autolock _l(mLock); | 
|  | mBatteryStatService.clear(); | 
|  | mDeathNotifier.clear(); | 
|  | // Do not reset mVideoRefCounts and mAudioRefCounts here. The ref | 
|  | // counting is independent of the battery service availability. | 
|  | // We need this if battery service becomes available after media | 
|  | // started. | 
|  |  | 
|  | } | 
|  |  | 
|  | sp<IBatteryStats> BatteryNotifier::getBatteryService_l() { | 
|  | if (mBatteryStatService != nullptr) { | 
|  | return mBatteryStatService; | 
|  | } | 
|  | // Get battery service from service manager | 
|  | const sp<IServiceManager> sm(defaultServiceManager()); | 
|  | if (sm != nullptr) { | 
|  | const String16 name("batterystats"); | 
|  | mBatteryStatService = interface_cast<IBatteryStats>(sm->checkService(name)); | 
|  | if (mBatteryStatService == nullptr) { | 
|  | // this may occur normally during the init sequence as mediaserver | 
|  | // and audioserver start before the batterystats service is available. | 
|  | ALOGW("batterystats service unavailable!"); | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | mDeathNotifier = new DeathNotifier(); | 
|  | IInterface::asBinder(mBatteryStatService)->linkToDeath(mDeathNotifier); | 
|  |  | 
|  | // Notify start now if mediaserver or audioserver is already started. | 
|  | // 1) mediaserver and audioserver is started before batterystats service | 
|  | // 2) batterystats server may have crashed. | 
|  | std::map<uid_t, int>::iterator it = mVideoRefCounts.begin(); | 
|  | for (; it != mVideoRefCounts.end(); ++it) { | 
|  | mBatteryStatService->noteStartVideo(it->first); | 
|  | } | 
|  | it = mAudioRefCounts.begin(); | 
|  | for (; it != mAudioRefCounts.end(); ++it) { | 
|  | mBatteryStatService->noteStartAudio(it->first); | 
|  | } | 
|  | // TODO: Notify for camera and flashlight state as well? | 
|  | } | 
|  | return mBatteryStatService; | 
|  | } | 
|  |  | 
|  | ANDROID_SINGLETON_STATIC_INSTANCE(BatteryNotifier); | 
|  |  | 
|  | }  // namespace android |