BatteryNotifier.cpp revision 1afd0983fdca07cd55df8dca1fa05b55c45063f4
1/*
2 * Copyright 2015, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "BatteryNotifier"
18//#define LOG_NDEBUG 0
19
20#include "include/mediautils/BatteryNotifier.h"
21
22#include <binder/IServiceManager.h>
23#include <utils/Log.h>
24#include <private/android_filesystem_config.h>
25
26namespace android {
27
28void BatteryNotifier::DeathNotifier::binderDied(const wp<IBinder>& /*who*/) {
29    BatteryNotifier::getInstance().onBatteryStatServiceDied();
30}
31
32BatteryNotifier::BatteryNotifier() {}
33
34BatteryNotifier::~BatteryNotifier() {
35    Mutex::Autolock _l(mLock);
36    if (mDeathNotifier != nullptr) {
37        IInterface::asBinder(mBatteryStatService)->unlinkToDeath(mDeathNotifier);
38    }
39}
40
41void BatteryNotifier::noteStartVideo(uid_t uid) {
42    Mutex::Autolock _l(mLock);
43    sp<IBatteryStats> batteryService = getBatteryService_l();
44    if (mVideoRefCounts[uid] == 0 && batteryService != nullptr) {
45        batteryService->noteStartVideo(uid);
46    }
47    mVideoRefCounts[uid]++;
48}
49
50void BatteryNotifier::noteStopVideo(uid_t uid) {
51    Mutex::Autolock _l(mLock);
52    if (mVideoRefCounts.find(uid) == mVideoRefCounts.end()) {
53        ALOGW("%s: video refcount is broken for uid(%d).", __FUNCTION__, (int)uid);
54        return;
55    }
56
57    sp<IBatteryStats> batteryService = getBatteryService_l();
58
59    mVideoRefCounts[uid]--;
60    if (mVideoRefCounts[uid] == 0) {
61        if (batteryService != nullptr) {
62            batteryService->noteStopVideo(uid);
63        }
64        mVideoRefCounts.erase(uid);
65    }
66}
67
68void BatteryNotifier::noteResetVideo() {
69    Mutex::Autolock _l(mLock);
70    sp<IBatteryStats> batteryService = getBatteryService_l();
71    mVideoRefCounts.clear();
72    if (batteryService != nullptr) {
73        batteryService->noteResetVideo();
74    }
75}
76
77void BatteryNotifier::noteStartAudio(uid_t uid) {
78    Mutex::Autolock _l(mLock);
79    sp<IBatteryStats> batteryService = getBatteryService_l();
80    if (mAudioRefCounts[uid] == 0 && batteryService != nullptr) {
81        batteryService->noteStartAudio(uid);
82    }
83    mAudioRefCounts[uid]++;
84}
85
86void BatteryNotifier::noteStopAudio(uid_t uid) {
87    Mutex::Autolock _l(mLock);
88    if (mAudioRefCounts.find(uid) == mAudioRefCounts.end()) {
89        ALOGW("%s: audio refcount is broken for uid(%d).", __FUNCTION__, (int)uid);
90        return;
91    }
92
93    sp<IBatteryStats> batteryService = getBatteryService_l();
94
95    mAudioRefCounts[uid]--;
96    if (mAudioRefCounts[uid] == 0) {
97        if (batteryService != nullptr) {
98            batteryService->noteStopAudio(uid);
99        }
100        mAudioRefCounts.erase(uid);
101    }
102}
103
104void BatteryNotifier::noteResetAudio() {
105    Mutex::Autolock _l(mLock);
106    sp<IBatteryStats> batteryService = getBatteryService_l();
107    mAudioRefCounts.clear();
108    if (batteryService != nullptr) {
109        batteryService->noteResetAudio();
110    }
111}
112
113void BatteryNotifier::noteFlashlightOn(const String8& id, uid_t uid) {
114    Mutex::Autolock _l(mLock);
115    sp<IBatteryStats> batteryService = getBatteryService_l();
116
117    std::pair<String8, uid_t> k = std::make_pair(id, uid);
118    if (!mFlashlightState[k]) {
119        mFlashlightState[k] = true;
120        if (batteryService != nullptr) {
121            batteryService->noteFlashlightOn(uid);
122        }
123    }
124}
125
126void BatteryNotifier::noteFlashlightOff(const String8& id, uid_t uid) {
127    Mutex::Autolock _l(mLock);
128    sp<IBatteryStats> batteryService = getBatteryService_l();
129
130    std::pair<String8, uid_t> k = std::make_pair(id, uid);
131    if (mFlashlightState[k]) {
132        mFlashlightState[k] = false;
133        if (batteryService != nullptr) {
134            batteryService->noteFlashlightOff(uid);
135        }
136    }
137}
138
139void BatteryNotifier::noteResetFlashlight() {
140    Mutex::Autolock _l(mLock);
141    sp<IBatteryStats> batteryService = getBatteryService_l();
142    mFlashlightState.clear();
143    if (batteryService != nullptr) {
144        batteryService->noteResetFlashlight();
145    }
146}
147
148void BatteryNotifier::noteStartCamera(const String8& id, uid_t uid) {
149    Mutex::Autolock _l(mLock);
150    sp<IBatteryStats> batteryService = getBatteryService_l();
151    std::pair<String8, uid_t> k = std::make_pair(id, uid);
152    if (!mCameraState[k]) {
153        mCameraState[k] = true;
154        if (batteryService != nullptr) {
155            batteryService->noteStartCamera(uid);
156        }
157    }
158}
159
160void BatteryNotifier::noteStopCamera(const String8& id, uid_t uid) {
161    Mutex::Autolock _l(mLock);
162    sp<IBatteryStats> batteryService = getBatteryService_l();
163    std::pair<String8, uid_t> k = std::make_pair(id, uid);
164    if (mCameraState[k]) {
165        mCameraState[k] = false;
166        if (batteryService != nullptr) {
167            batteryService->noteStopCamera(uid);
168        }
169    }
170}
171
172void BatteryNotifier::noteResetCamera() {
173    Mutex::Autolock _l(mLock);
174    sp<IBatteryStats> batteryService = getBatteryService_l();
175    mCameraState.clear();
176    if (batteryService != nullptr) {
177        batteryService->noteResetCamera();
178    }
179}
180
181void BatteryNotifier::onBatteryStatServiceDied() {
182    Mutex::Autolock _l(mLock);
183    mBatteryStatService.clear();
184    mDeathNotifier.clear();
185    // Do not reset mVideoRefCounts and mAudioRefCounts here. The ref
186    // counting is independent of the battery service availability.
187    // We need this if battery service becomes available after media
188    // started.
189
190}
191
192sp<IBatteryStats> BatteryNotifier::getBatteryService_l() {
193    if (mBatteryStatService != nullptr) {
194        return mBatteryStatService;
195    }
196    // Get battery service from service manager
197    const sp<IServiceManager> sm(defaultServiceManager());
198    if (sm != nullptr) {
199        const String16 name("batterystats");
200        mBatteryStatService = interface_cast<IBatteryStats>(sm->checkService(name));
201        if (mBatteryStatService == nullptr) {
202            // this may occur normally during the init sequence as mediaserver
203            // and audioserver start before the batterystats service is available.
204            ALOGW("batterystats service unavailable!");
205            return nullptr;
206        }
207
208        mDeathNotifier = new DeathNotifier();
209        IInterface::asBinder(mBatteryStatService)->linkToDeath(mDeathNotifier);
210
211        // Notify start now if mediaserver or audioserver is already started.
212        // 1) mediaserver and audioserver is started before batterystats service
213        // 2) batterystats server may have crashed.
214        std::map<uid_t, int>::iterator it = mVideoRefCounts.begin();
215        for (; it != mVideoRefCounts.end(); ++it) {
216            mBatteryStatService->noteStartVideo(it->first);
217        }
218        it = mAudioRefCounts.begin();
219        for (; it != mAudioRefCounts.end(); ++it) {
220            mBatteryStatService->noteStartAudio(it->first);
221        }
222        // TODO: Notify for camera and flashlight state as well?
223    }
224    return mBatteryStatService;
225}
226
227ANDROID_SINGLETON_STATIC_INSTANCE(BatteryNotifier);
228
229}  // namespace android
230