1/*
2 * Copyright (C) 2012 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#include <stdint.h>
18#include <math.h>
19#include <sys/types.h>
20
21#include <utils/Atomic.h>
22#include <utils/Errors.h>
23#include <utils/Singleton.h>
24
25#include <binder/BinderService.h>
26#include <binder/Parcel.h>
27
28#include "BatteryService.h"
29
30namespace android {
31// ---------------------------------------------------------------------------
32
33BatteryService::BatteryService() : mBatteryStatService(nullptr) {
34}
35
36bool BatteryService::addSensor(uid_t uid, int handle) {
37    Mutex::Autolock _l(mActivationsLock);
38    Info key(uid, handle);
39    ssize_t index = mActivations.indexOf(key);
40    if (index < 0) {
41        index = mActivations.add(key);
42    }
43    Info& info(mActivations.editItemAt(index));
44    info.count++;
45    return info.count == 1;
46}
47
48bool BatteryService::removeSensor(uid_t uid, int handle) {
49    Mutex::Autolock _l(mActivationsLock);
50    ssize_t index = mActivations.indexOf(Info(uid, handle));
51    if (index < 0) return false;
52    Info& info(mActivations.editItemAt(index));
53    info.count--;
54    return info.count == 0;
55}
56
57
58void BatteryService::enableSensorImpl(uid_t uid, int handle) {
59    if (checkService()) {
60        if (addSensor(uid, handle)) {
61            int64_t identity = IPCThreadState::self()->clearCallingIdentity();
62            mBatteryStatService->noteStartSensor(uid, handle);
63            IPCThreadState::self()->restoreCallingIdentity(identity);
64        }
65    }
66}
67void BatteryService::disableSensorImpl(uid_t uid, int handle) {
68    if (checkService()) {
69        if (removeSensor(uid, handle)) {
70            int64_t identity = IPCThreadState::self()->clearCallingIdentity();
71            mBatteryStatService->noteStopSensor(uid, handle);
72            IPCThreadState::self()->restoreCallingIdentity(identity);
73        }
74    }
75}
76
77void BatteryService::cleanupImpl(uid_t uid) {
78    if (checkService()) {
79        Mutex::Autolock _l(mActivationsLock);
80        int64_t identity = IPCThreadState::self()->clearCallingIdentity();
81        for (size_t i=0 ; i<mActivations.size() ; i++) {
82            const Info& info(mActivations[i]);
83            if (info.uid == uid) {
84                mBatteryStatService->noteStopSensor(info.uid, info.handle);
85                mActivations.removeAt(i);
86                i--;
87            }
88        }
89        IPCThreadState::self()->restoreCallingIdentity(identity);
90    }
91}
92
93bool BatteryService::checkService() {
94    if (mBatteryStatService == nullptr) {
95        const sp<IServiceManager> sm(defaultServiceManager());
96        if (sm != NULL) {
97            const String16 name("batterystats");
98            mBatteryStatService = interface_cast<IBatteryStats>(sm->getService(name));
99        }
100    }
101    return mBatteryStatService != nullptr;
102}
103
104ANDROID_SINGLETON_STATIC_INSTANCE(BatteryService)
105
106// ---------------------------------------------------------------------------
107}; // namespace android
108
109