199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk/* 299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk * Copyright 2015, The Android Open Source Project 399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk * 499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk * Licensed under the Apache License, Version 2.0 (the "License"); 599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk * you may not use this file except in compliance with the License. 699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk * You may obtain a copy of the License at 799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk * 899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk * http://www.apache.org/licenses/LICENSE-2.0 999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk * 1099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk * Unless required by applicable law or agreed to in writing, software 1199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk * distributed under the License is distributed on an "AS IS" BASIS, 1299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk * See the License for the specific language governing permissions and 1499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk * limitations under the License. 1599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk */ 1699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 17dcb346b7dc5b88c3e85db8a70bbd6a2fee8192b9Marco Nelissen#define LOG_TAG "BatteryNotifier" 18dcb346b7dc5b88c3e85db8a70bbd6a2fee8192b9Marco Nelissen//#define LOG_NDEBUG 0 19dcb346b7dc5b88c3e85db8a70bbd6a2fee8192b9Marco Nelissen 2099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk#include "include/mediautils/BatteryNotifier.h" 2199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 2299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk#include <binder/IServiceManager.h> 2399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk#include <utils/Log.h> 2499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk#include <private/android_filesystem_config.h> 2599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 2699e69716215cd0665379bc90d708f2ea8689831dRuben Brunknamespace android { 2799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 2899e69716215cd0665379bc90d708f2ea8689831dRuben Brunkvoid BatteryNotifier::DeathNotifier::binderDied(const wp<IBinder>& /*who*/) { 2999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk BatteryNotifier::getInstance().onBatteryStatServiceDied(); 3099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk} 3199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 32f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei JiaBatteryNotifier::BatteryNotifier() {} 3399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 3499e69716215cd0665379bc90d708f2ea8689831dRuben BrunkBatteryNotifier::~BatteryNotifier() { 3599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk Mutex::Autolock _l(mLock); 3699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk if (mDeathNotifier != nullptr) { 3799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk IInterface::asBinder(mBatteryStatService)->unlinkToDeath(mDeathNotifier); 3899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk } 3999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk} 4099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 411afd0983fdca07cd55df8dca1fa05b55c45063f4Andy Hungvoid BatteryNotifier::noteStartVideo(uid_t uid) { 4299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk Mutex::Autolock _l(mLock); 4399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk sp<IBatteryStats> batteryService = getBatteryService_l(); 44f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia if (mVideoRefCounts[uid] == 0 && batteryService != nullptr) { 45f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia batteryService->noteStartVideo(uid); 4699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk } 47f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia mVideoRefCounts[uid]++; 4899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk} 4999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 501afd0983fdca07cd55df8dca1fa05b55c45063f4Andy Hungvoid BatteryNotifier::noteStopVideo(uid_t uid) { 5199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk Mutex::Autolock _l(mLock); 52f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia if (mVideoRefCounts.find(uid) == mVideoRefCounts.end()) { 53f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia ALOGW("%s: video refcount is broken for uid(%d).", __FUNCTION__, (int)uid); 5499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk return; 5599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk } 5699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 5799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk sp<IBatteryStats> batteryService = getBatteryService_l(); 5899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 59f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia mVideoRefCounts[uid]--; 60f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia if (mVideoRefCounts[uid] == 0) { 61f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia if (batteryService != nullptr) { 62f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia batteryService->noteStopVideo(uid); 63f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia } 64f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia mVideoRefCounts.erase(uid); 6599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk } 6699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk} 6799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 6899e69716215cd0665379bc90d708f2ea8689831dRuben Brunkvoid BatteryNotifier::noteResetVideo() { 6999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk Mutex::Autolock _l(mLock); 7099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk sp<IBatteryStats> batteryService = getBatteryService_l(); 71f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia mVideoRefCounts.clear(); 7299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk if (batteryService != nullptr) { 73dcb346b7dc5b88c3e85db8a70bbd6a2fee8192b9Marco Nelissen batteryService->noteResetVideo(); 7499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk } 7599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk} 7699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 771afd0983fdca07cd55df8dca1fa05b55c45063f4Andy Hungvoid BatteryNotifier::noteStartAudio(uid_t uid) { 7899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk Mutex::Autolock _l(mLock); 7999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk sp<IBatteryStats> batteryService = getBatteryService_l(); 80f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia if (mAudioRefCounts[uid] == 0 && batteryService != nullptr) { 81f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia batteryService->noteStartAudio(uid); 8299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk } 83f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia mAudioRefCounts[uid]++; 8499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk} 8599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 861afd0983fdca07cd55df8dca1fa05b55c45063f4Andy Hungvoid BatteryNotifier::noteStopAudio(uid_t uid) { 8799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk Mutex::Autolock _l(mLock); 88f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia if (mAudioRefCounts.find(uid) == mAudioRefCounts.end()) { 89f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia ALOGW("%s: audio refcount is broken for uid(%d).", __FUNCTION__, (int)uid); 9099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk return; 9199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk } 9299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 9399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk sp<IBatteryStats> batteryService = getBatteryService_l(); 9499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 95f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia mAudioRefCounts[uid]--; 96f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia if (mAudioRefCounts[uid] == 0) { 97f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia if (batteryService != nullptr) { 98f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia batteryService->noteStopAudio(uid); 99f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia } 100f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia mAudioRefCounts.erase(uid); 10199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk } 10299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk} 10399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 10499e69716215cd0665379bc90d708f2ea8689831dRuben Brunkvoid BatteryNotifier::noteResetAudio() { 10599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk Mutex::Autolock _l(mLock); 10699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk sp<IBatteryStats> batteryService = getBatteryService_l(); 107f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia mAudioRefCounts.clear(); 10899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk if (batteryService != nullptr) { 10999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk batteryService->noteResetAudio(); 11099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk } 11199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk} 11299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 1131afd0983fdca07cd55df8dca1fa05b55c45063f4Andy Hungvoid BatteryNotifier::noteFlashlightOn(const String8& id, uid_t uid) { 11499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk Mutex::Autolock _l(mLock); 11599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk sp<IBatteryStats> batteryService = getBatteryService_l(); 11699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 1171afd0983fdca07cd55df8dca1fa05b55c45063f4Andy Hung std::pair<String8, uid_t> k = std::make_pair(id, uid); 11899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk if (!mFlashlightState[k]) { 11999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk mFlashlightState[k] = true; 12099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk if (batteryService != nullptr) { 12199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk batteryService->noteFlashlightOn(uid); 12299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk } 12399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk } 12499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk} 12599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 1261afd0983fdca07cd55df8dca1fa05b55c45063f4Andy Hungvoid BatteryNotifier::noteFlashlightOff(const String8& id, uid_t uid) { 12799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk Mutex::Autolock _l(mLock); 12899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk sp<IBatteryStats> batteryService = getBatteryService_l(); 12999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 1301afd0983fdca07cd55df8dca1fa05b55c45063f4Andy Hung std::pair<String8, uid_t> k = std::make_pair(id, uid); 13199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk if (mFlashlightState[k]) { 13299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk mFlashlightState[k] = false; 13399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk if (batteryService != nullptr) { 13499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk batteryService->noteFlashlightOff(uid); 13599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk } 13699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk } 13799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk} 13899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 13999e69716215cd0665379bc90d708f2ea8689831dRuben Brunkvoid BatteryNotifier::noteResetFlashlight() { 14099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk Mutex::Autolock _l(mLock); 14199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk sp<IBatteryStats> batteryService = getBatteryService_l(); 14299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk mFlashlightState.clear(); 14399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk if (batteryService != nullptr) { 14499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk batteryService->noteResetFlashlight(); 14599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk } 14699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk} 14799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 1481afd0983fdca07cd55df8dca1fa05b55c45063f4Andy Hungvoid BatteryNotifier::noteStartCamera(const String8& id, uid_t uid) { 14999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk Mutex::Autolock _l(mLock); 15099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk sp<IBatteryStats> batteryService = getBatteryService_l(); 1511afd0983fdca07cd55df8dca1fa05b55c45063f4Andy Hung std::pair<String8, uid_t> k = std::make_pair(id, uid); 15299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk if (!mCameraState[k]) { 15399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk mCameraState[k] = true; 15499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk if (batteryService != nullptr) { 15599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk batteryService->noteStartCamera(uid); 15699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk } 15799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk } 15899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk} 15999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 1601afd0983fdca07cd55df8dca1fa05b55c45063f4Andy Hungvoid BatteryNotifier::noteStopCamera(const String8& id, uid_t uid) { 16199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk Mutex::Autolock _l(mLock); 16299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk sp<IBatteryStats> batteryService = getBatteryService_l(); 1631afd0983fdca07cd55df8dca1fa05b55c45063f4Andy Hung std::pair<String8, uid_t> k = std::make_pair(id, uid); 16499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk if (mCameraState[k]) { 16599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk mCameraState[k] = false; 16699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk if (batteryService != nullptr) { 16799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk batteryService->noteStopCamera(uid); 16899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk } 16999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk } 17099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk} 17199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 17299e69716215cd0665379bc90d708f2ea8689831dRuben Brunkvoid BatteryNotifier::noteResetCamera() { 17399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk Mutex::Autolock _l(mLock); 17499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk sp<IBatteryStats> batteryService = getBatteryService_l(); 17599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk mCameraState.clear(); 17699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk if (batteryService != nullptr) { 17799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk batteryService->noteResetCamera(); 17899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk } 17999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk} 18099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 18199e69716215cd0665379bc90d708f2ea8689831dRuben Brunkvoid BatteryNotifier::onBatteryStatServiceDied() { 18299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk Mutex::Autolock _l(mLock); 18399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk mBatteryStatService.clear(); 18499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk mDeathNotifier.clear(); 185f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia // Do not reset mVideoRefCounts and mAudioRefCounts here. The ref 18699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk // counting is independent of the battery service availability. 18799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk // We need this if battery service becomes available after media 18899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk // started. 18999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 19099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk} 19199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 19299e69716215cd0665379bc90d708f2ea8689831dRuben Brunksp<IBatteryStats> BatteryNotifier::getBatteryService_l() { 19399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk if (mBatteryStatService != nullptr) { 19499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk return mBatteryStatService; 19599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk } 19699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk // Get battery service from service manager 19799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk const sp<IServiceManager> sm(defaultServiceManager()); 19899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk if (sm != nullptr) { 19999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk const String16 name("batterystats"); 20099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk mBatteryStatService = interface_cast<IBatteryStats>(sm->checkService(name)); 20199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk if (mBatteryStatService == nullptr) { 202dcb346b7dc5b88c3e85db8a70bbd6a2fee8192b9Marco Nelissen // this may occur normally during the init sequence as mediaserver 203dcb346b7dc5b88c3e85db8a70bbd6a2fee8192b9Marco Nelissen // and audioserver start before the batterystats service is available. 204dcb346b7dc5b88c3e85db8a70bbd6a2fee8192b9Marco Nelissen ALOGW("batterystats service unavailable!"); 20599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk return nullptr; 20699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk } 20799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 20899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk mDeathNotifier = new DeathNotifier(); 20999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk IInterface::asBinder(mBatteryStatService)->linkToDeath(mDeathNotifier); 21099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 211dcb346b7dc5b88c3e85db8a70bbd6a2fee8192b9Marco Nelissen // Notify start now if mediaserver or audioserver is already started. 212dcb346b7dc5b88c3e85db8a70bbd6a2fee8192b9Marco Nelissen // 1) mediaserver and audioserver is started before batterystats service 213dcb346b7dc5b88c3e85db8a70bbd6a2fee8192b9Marco Nelissen // 2) batterystats server may have crashed. 2141afd0983fdca07cd55df8dca1fa05b55c45063f4Andy Hung std::map<uid_t, int>::iterator it = mVideoRefCounts.begin(); 215f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia for (; it != mVideoRefCounts.end(); ++it) { 216f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia mBatteryStatService->noteStartVideo(it->first); 21799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk } 218f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia it = mAudioRefCounts.begin(); 219f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia for (; it != mAudioRefCounts.end(); ++it) { 220f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia mBatteryStatService->noteStartAudio(it->first); 22199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk } 222dcb346b7dc5b88c3e85db8a70bbd6a2fee8192b9Marco Nelissen // TODO: Notify for camera and flashlight state as well? 22399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk } 22499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk return mBatteryStatService; 22599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk} 22699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 22799e69716215cd0665379bc90d708f2ea8689831dRuben BrunkANDROID_SINGLETON_STATIC_INSTANCE(BatteryNotifier); 22899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk 22999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk} // namespace android 230