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
26 namespace android {
27
binderDied(const wp<IBinder> &)28 void BatteryNotifier::DeathNotifier::binderDied(const wp<IBinder>& /*who*/) {
29 BatteryNotifier::getInstance().onBatteryStatServiceDied();
30 }
31
BatteryNotifier()32 BatteryNotifier::BatteryNotifier() {}
33
~BatteryNotifier()34 BatteryNotifier::~BatteryNotifier() {
35 Mutex::Autolock _l(mLock);
36 if (mDeathNotifier != nullptr) {
37 IInterface::asBinder(mBatteryStatService)->unlinkToDeath(mDeathNotifier);
38 }
39 }
40
noteStartVideo(uid_t uid)41 void 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
noteStopVideo(uid_t uid)50 void 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
noteResetVideo()68 void 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
noteStartAudio(uid_t uid)77 void 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
noteStopAudio(uid_t uid)86 void 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
noteResetAudio()104 void 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
noteFlashlightOn(const String8 & id,uid_t uid)113 void 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
noteFlashlightOff(const String8 & id,uid_t uid)126 void 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
noteResetFlashlight()139 void 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
noteStartCamera(const String8 & id,uid_t uid)148 void 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
noteStopCamera(const String8 & id,uid_t uid)160 void 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
noteResetCamera()172 void 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
onBatteryStatServiceDied()181 void 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
getBatteryService_l()192 sp<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
227 ANDROID_SINGLETON_STATIC_INSTANCE(BatteryNotifier);
228
229 } // namespace android
230