1 /*
2 * Copyright (C) 2010 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 #include <binder/IServiceManager.h>
28
29 #include <hardware/sensors.h>
30
31 #include "SensorDevice.h"
32 #include "SensorService.h"
33
34 namespace android {
35 // ---------------------------------------------------------------------------
36 class BatteryService : public Singleton<BatteryService> {
37 static const int TRANSACTION_noteStartSensor = IBinder::FIRST_CALL_TRANSACTION + 3;
38 static const int TRANSACTION_noteStopSensor = IBinder::FIRST_CALL_TRANSACTION + 4;
39 static const String16 DESCRIPTOR;
40
41 friend class Singleton<BatteryService>;
42 sp<IBinder> mBatteryStatService;
43
BatteryService()44 BatteryService() {
45 const sp<IServiceManager> sm(defaultServiceManager());
46 if (sm != NULL) {
47 const String16 name("batteryinfo");
48 mBatteryStatService = sm->getService(name);
49 }
50 }
51
noteStartSensor(int uid,int handle)52 status_t noteStartSensor(int uid, int handle) {
53 Parcel data, reply;
54 data.writeInterfaceToken(DESCRIPTOR);
55 data.writeInt32(uid);
56 data.writeInt32(handle);
57 status_t err = mBatteryStatService->transact(
58 TRANSACTION_noteStartSensor, data, &reply, 0);
59 err = reply.readExceptionCode();
60 return err;
61 }
62
noteStopSensor(int uid,int handle)63 status_t noteStopSensor(int uid, int handle) {
64 Parcel data, reply;
65 data.writeInterfaceToken(DESCRIPTOR);
66 data.writeInt32(uid);
67 data.writeInt32(handle);
68 status_t err = mBatteryStatService->transact(
69 TRANSACTION_noteStopSensor, data, &reply, 0);
70 err = reply.readExceptionCode();
71 return err;
72 }
73
74 public:
enableSensor(int handle)75 void enableSensor(int handle) {
76 if (mBatteryStatService != 0) {
77 int uid = IPCThreadState::self()->getCallingUid();
78 int64_t identity = IPCThreadState::self()->clearCallingIdentity();
79 noteStartSensor(uid, handle);
80 IPCThreadState::self()->restoreCallingIdentity(identity);
81 }
82 }
disableSensor(int handle)83 void disableSensor(int handle) {
84 if (mBatteryStatService != 0) {
85 int uid = IPCThreadState::self()->getCallingUid();
86 int64_t identity = IPCThreadState::self()->clearCallingIdentity();
87 noteStopSensor(uid, handle);
88 IPCThreadState::self()->restoreCallingIdentity(identity);
89 }
90 }
91 };
92
93 const String16 BatteryService::DESCRIPTOR("com.android.internal.app.IBatteryStats");
94
95 ANDROID_SINGLETON_STATIC_INSTANCE(BatteryService)
96
97 // ---------------------------------------------------------------------------
98
ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice)99 ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice)
100
101 SensorDevice::SensorDevice()
102 : mSensorDevice(0),
103 mSensorModule(0)
104 {
105 status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
106 (hw_module_t const**)&mSensorModule);
107
108 ALOGE_IF(err, "couldn't load %s module (%s)",
109 SENSORS_HARDWARE_MODULE_ID, strerror(-err));
110
111 if (mSensorModule) {
112 err = sensors_open(&mSensorModule->common, &mSensorDevice);
113
114 ALOGE_IF(err, "couldn't open device for module %s (%s)",
115 SENSORS_HARDWARE_MODULE_ID, strerror(-err));
116
117 if (mSensorDevice) {
118 sensor_t const* list;
119 ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
120 mActivationCount.setCapacity(count);
121 Info model;
122 for (size_t i=0 ; i<size_t(count) ; i++) {
123 mActivationCount.add(list[i].handle, model);
124 mSensorDevice->activate(mSensorDevice, list[i].handle, 0);
125 }
126 }
127 }
128 }
129
dump(String8 & result,char * buffer,size_t SIZE)130 void SensorDevice::dump(String8& result, char* buffer, size_t SIZE)
131 {
132 if (!mSensorModule) return;
133 sensor_t const* list;
134 ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
135
136 snprintf(buffer, SIZE, "%d h/w sensors:\n", int(count));
137 result.append(buffer);
138
139 Mutex::Autolock _l(mLock);
140 for (size_t i=0 ; i<size_t(count) ; i++) {
141 const Info& info = mActivationCount.valueFor(list[i].handle);
142 snprintf(buffer, SIZE, "handle=0x%08x, active-count=%d, rates(ms)={ ",
143 list[i].handle,
144 info.rates.size());
145 result.append(buffer);
146 for (size_t j=0 ; j<info.rates.size() ; j++) {
147 snprintf(buffer, SIZE, "%4.1f%s",
148 info.rates.valueAt(j) / 1e6f,
149 j<info.rates.size()-1 ? ", " : "");
150 result.append(buffer);
151 }
152 snprintf(buffer, SIZE, " }, selected=%4.1f ms\n", info.delay / 1e6f);
153 result.append(buffer);
154 }
155 }
156
getSensorList(sensor_t const ** list)157 ssize_t SensorDevice::getSensorList(sensor_t const** list) {
158 if (!mSensorModule) return NO_INIT;
159 ssize_t count = mSensorModule->get_sensors_list(mSensorModule, list);
160 return count;
161 }
162
initCheck() const163 status_t SensorDevice::initCheck() const {
164 return mSensorDevice && mSensorModule ? NO_ERROR : NO_INIT;
165 }
166
poll(sensors_event_t * buffer,size_t count)167 ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
168 if (!mSensorDevice) return NO_INIT;
169 ssize_t c;
170 do {
171 c = mSensorDevice->poll(mSensorDevice, buffer, count);
172 } while (c == -EINTR);
173 return c;
174 }
175
activate(void * ident,int handle,int enabled)176 status_t SensorDevice::activate(void* ident, int handle, int enabled)
177 {
178 if (!mSensorDevice) return NO_INIT;
179 status_t err(NO_ERROR);
180 bool actuateHardware = false;
181
182 Info& info( mActivationCount.editValueFor(handle) );
183
184
185 ALOGD_IF(DEBUG_CONNECTIONS,
186 "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%d",
187 ident, handle, enabled, info.rates.size());
188
189 if (enabled) {
190 Mutex::Autolock _l(mLock);
191 ALOGD_IF(DEBUG_CONNECTIONS, "... index=%ld",
192 info.rates.indexOfKey(ident));
193
194 if (info.rates.indexOfKey(ident) < 0) {
195 info.rates.add(ident, DEFAULT_EVENTS_PERIOD);
196 if (info.rates.size() == 1) {
197 actuateHardware = true;
198 }
199 } else {
200 // sensor was already activated for this ident
201 }
202 } else {
203 Mutex::Autolock _l(mLock);
204 ALOGD_IF(DEBUG_CONNECTIONS, "... index=%ld",
205 info.rates.indexOfKey(ident));
206
207 ssize_t idx = info.rates.removeItem(ident);
208 if (idx >= 0) {
209 if (info.rates.size() == 0) {
210 actuateHardware = true;
211 }
212 } else {
213 // sensor wasn't enabled for this ident
214 }
215 }
216
217 if (actuateHardware) {
218 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w");
219
220 err = mSensorDevice->activate(mSensorDevice, handle, enabled);
221 if (enabled) {
222 ALOGE_IF(err, "Error activating sensor %d (%s)", handle, strerror(-err));
223 if (err == 0) {
224 BatteryService::getInstance().enableSensor(handle);
225 }
226 } else {
227 if (err == 0) {
228 BatteryService::getInstance().disableSensor(handle);
229 }
230 }
231 }
232
233 { // scope for the lock
234 Mutex::Autolock _l(mLock);
235 nsecs_t ns = info.selectDelay();
236 mSensorDevice->setDelay(mSensorDevice, handle, ns);
237 }
238
239 return err;
240 }
241
setDelay(void * ident,int handle,int64_t ns)242 status_t SensorDevice::setDelay(void* ident, int handle, int64_t ns)
243 {
244 if (!mSensorDevice) return NO_INIT;
245 Mutex::Autolock _l(mLock);
246 Info& info( mActivationCount.editValueFor(handle) );
247 status_t err = info.setDelayForIdent(ident, ns);
248 if (err < 0) return err;
249 ns = info.selectDelay();
250 return mSensorDevice->setDelay(mSensorDevice, handle, ns);
251 }
252
253 // ---------------------------------------------------------------------------
254
setDelayForIdent(void * ident,int64_t ns)255 status_t SensorDevice::Info::setDelayForIdent(void* ident, int64_t ns)
256 {
257 ssize_t index = rates.indexOfKey(ident);
258 if (index < 0) {
259 ALOGE("Info::setDelayForIdent(ident=%p, ns=%lld) failed (%s)",
260 ident, ns, strerror(-index));
261 return BAD_INDEX;
262 }
263 rates.editValueAt(index) = ns;
264 return NO_ERROR;
265 }
266
selectDelay()267 nsecs_t SensorDevice::Info::selectDelay()
268 {
269 nsecs_t ns = rates.valueAt(0);
270 for (size_t i=1 ; i<rates.size() ; i++) {
271 nsecs_t cur = rates.valueAt(i);
272 if (cur < ns) {
273 ns = cur;
274 }
275 }
276 delay = ns;
277 return ns;
278 }
279
280 // ---------------------------------------------------------------------------
281 }; // namespace android
282
283