summaryrefslogtreecommitdiffstats
path: root/media/utils/BatteryNotifier.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/utils/BatteryNotifier.cpp')
-rw-r--r--media/utils/BatteryNotifier.cpp213
1 files changed, 213 insertions, 0 deletions
diff --git a/media/utils/BatteryNotifier.cpp b/media/utils/BatteryNotifier.cpp
new file mode 100644
index 0000000..7f9cd7a
--- /dev/null
+++ b/media/utils/BatteryNotifier.cpp
@@ -0,0 +1,213 @@
+/*
+ * 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.
+ */
+
+#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->noteResetAudio();
+ }
+}
+
+void BatteryNotifier::noteStartAudio() {
+ Mutex::Autolock _l(mLock);
+ sp<IBatteryStats> batteryService = getBatteryService_l();
+ if (mAudioRefCount == 0 && batteryService != nullptr) {
+ batteryService->noteStartAudio(AID_MEDIA);
+ }
+ 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_MEDIA);
+ }
+}
+
+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) {
+ ALOGE("batterystats service unavailable!");
+ return nullptr;
+ }
+
+ mDeathNotifier = new DeathNotifier();
+ IInterface::asBinder(mBatteryStatService)->linkToDeath(mDeathNotifier);
+
+ // Notify start now if media already started
+ if (mVideoRefCount > 0) {
+ mBatteryStatService->noteStartVideo(AID_MEDIA);
+ }
+ if (mAudioRefCount > 0) {
+ mBatteryStatService->noteStartAudio(AID_MEDIA);
+ }
+ }
+ return mBatteryStatService;
+}
+
+ANDROID_SINGLETON_STATIC_INSTANCE(BatteryNotifier);
+
+} // namespace android