| /* |
| * 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() : mVideoRefCount(0), mAudioRefCount(0) {} |
| |
| BatteryNotifier::~BatteryNotifier() { |
| Mutex::Autolock _l(mLock); |
| if (mDeathNotifier != nullptr) { |
| IInterface::asBinder(mBatteryStatService)->unlinkToDeath(mDeathNotifier); |
| } |
| } |
| |
| void BatteryNotifier::noteStartVideo() { |
| Mutex::Autolock _l(mLock); |
| sp<IBatteryStats> batteryService = getBatteryService_l(); |
| if (mVideoRefCount == 0 && batteryService != nullptr) { |
| batteryService->noteStartVideo(AID_MEDIA); |
| } |
| mVideoRefCount++; |
| } |
| |
| void BatteryNotifier::noteStopVideo() { |
| Mutex::Autolock _l(mLock); |
| if (mVideoRefCount == 0) { |
| ALOGW("%s: video refcount is broken.", __FUNCTION__); |
| return; |
| } |
| |
| sp<IBatteryStats> batteryService = getBatteryService_l(); |
| |
| mVideoRefCount--; |
| if (mVideoRefCount == 0 && batteryService != nullptr) { |
| batteryService->noteStopVideo(AID_MEDIA); |
| } |
| } |
| |
| void BatteryNotifier::noteResetVideo() { |
| Mutex::Autolock _l(mLock); |
| sp<IBatteryStats> batteryService = getBatteryService_l(); |
| mVideoRefCount = 0; |
| if (batteryService != nullptr) { |
| batteryService->noteResetVideo(); |
| } |
| } |
| |
| void BatteryNotifier::noteStartAudio() { |
| Mutex::Autolock _l(mLock); |
| sp<IBatteryStats> batteryService = getBatteryService_l(); |
| if (mAudioRefCount == 0 && batteryService != nullptr) { |
| batteryService->noteStartAudio(AID_AUDIOSERVER); |
| } |
| mAudioRefCount++; |
| } |
| |
| void BatteryNotifier::noteStopAudio() { |
| Mutex::Autolock _l(mLock); |
| if (mAudioRefCount == 0) { |
| ALOGW("%s: audio refcount is broken.", __FUNCTION__); |
| return; |
| } |
| |
| sp<IBatteryStats> batteryService = getBatteryService_l(); |
| |
| mAudioRefCount--; |
| if (mAudioRefCount == 0 && batteryService != nullptr) { |
| batteryService->noteStopAudio(AID_AUDIOSERVER); |
| } |
| } |
| |
| void BatteryNotifier::noteResetAudio() { |
| Mutex::Autolock _l(mLock); |
| sp<IBatteryStats> batteryService = getBatteryService_l(); |
| mAudioRefCount = 0; |
| if (batteryService != nullptr) { |
| batteryService->noteResetAudio(); |
| } |
| } |
| |
| void BatteryNotifier::noteFlashlightOn(const String8& id, int uid) { |
| Mutex::Autolock _l(mLock); |
| sp<IBatteryStats> batteryService = getBatteryService_l(); |
| |
| std::pair<String8, int> k = std::make_pair(id, uid); |
| if (!mFlashlightState[k]) { |
| mFlashlightState[k] = true; |
| if (batteryService != nullptr) { |
| batteryService->noteFlashlightOn(uid); |
| } |
| } |
| } |
| |
| void BatteryNotifier::noteFlashlightOff(const String8& id, int uid) { |
| Mutex::Autolock _l(mLock); |
| sp<IBatteryStats> batteryService = getBatteryService_l(); |
| |
| std::pair<String8, int> 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, int uid) { |
| Mutex::Autolock _l(mLock); |
| sp<IBatteryStats> batteryService = getBatteryService_l(); |
| std::pair<String8, int> k = std::make_pair(id, uid); |
| if (!mCameraState[k]) { |
| mCameraState[k] = true; |
| if (batteryService != nullptr) { |
| batteryService->noteStartCamera(uid); |
| } |
| } |
| } |
| |
| void BatteryNotifier::noteStopCamera(const String8& id, int uid) { |
| Mutex::Autolock _l(mLock); |
| sp<IBatteryStats> batteryService = getBatteryService_l(); |
| std::pair<String8, int> 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 mVideoRefCount and mAudioRefCount 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. |
| if (mVideoRefCount > 0) { |
| mBatteryStatService->noteStartVideo(AID_MEDIA); |
| } |
| if (mAudioRefCount > 0) { |
| mBatteryStatService->noteStartAudio(AID_AUDIOSERVER); |
| } |
| // TODO: Notify for camera and flashlight state as well? |
| } |
| return mBatteryStatService; |
| } |
| |
| ANDROID_SINGLETON_STATIC_INSTANCE(BatteryNotifier); |
| |
| } // namespace android |