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 <inttypes.h>
18 #include <math.h>
19 #include <stdint.h>
20 #include <sys/types.h>
21 
22 #include <utils/Atomic.h>
23 #include <utils/Errors.h>
24 #include <utils/Singleton.h>
25 
26 #include <binder/BinderService.h>
27 #include <binder/Parcel.h>
28 #include <binder/IServiceManager.h>
29 
30 #include <hardware/sensors.h>
31 
32 #include "SensorDevice.h"
33 #include "SensorService.h"
34 
35 namespace android {
36 // ---------------------------------------------------------------------------
37 
ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice)38 ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice)
39 
40 SensorDevice::SensorDevice()
41     :  mSensorDevice(0),
42        mSensorModule(0)
43 {
44     status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
45             (hw_module_t const**)&mSensorModule);
46 
47     ALOGE_IF(err, "couldn't load %s module (%s)",
48             SENSORS_HARDWARE_MODULE_ID, strerror(-err));
49 
50     if (mSensorModule) {
51         err = sensors_open_1(&mSensorModule->common, &mSensorDevice);
52 
53         ALOGE_IF(err, "couldn't open device for module %s (%s)",
54                 SENSORS_HARDWARE_MODULE_ID, strerror(-err));
55 
56         if (mSensorDevice) {
57             if (mSensorDevice->common.version == SENSORS_DEVICE_API_VERSION_1_1 ||
58                 mSensorDevice->common.version == SENSORS_DEVICE_API_VERSION_1_2) {
59                 ALOGE(">>>> WARNING <<< Upgrade sensor HAL to version 1_3");
60             }
61 
62             sensor_t const* list;
63             ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
64             mActivationCount.setCapacity(count);
65             Info model;
66             for (size_t i=0 ; i<size_t(count) ; i++) {
67                 mActivationCount.add(list[i].handle, model);
68                 mSensorDevice->activate(
69                         reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
70                         list[i].handle, 0);
71             }
72         }
73     }
74 }
75 
dump(String8 & result)76 void SensorDevice::dump(String8& result)
77 {
78     if (!mSensorModule) return;
79     sensor_t const* list;
80     ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
81 
82     result.appendFormat("halVersion %d\n", getHalDeviceVersion());
83     result.appendFormat("%d h/w sensors:\n", int(count));
84 
85     Mutex::Autolock _l(mLock);
86     for (size_t i=0 ; i<size_t(count) ; i++) {
87         const Info& info = mActivationCount.valueFor(list[i].handle);
88         result.appendFormat("handle=0x%08x, active-count=%zu, batch_period(ms)={ ", list[i].handle,
89                             info.batchParams.size());
90         for (size_t j = 0; j < info.batchParams.size(); j++) {
91             BatchParams params = info.batchParams.valueAt(j);
92             result.appendFormat("%4.1f%s", params.batchDelay / 1e6f,
93                                 j < info.batchParams.size() - 1 ? ", " : "");
94         }
95         result.appendFormat(" }, selected=%4.1f ms\n", info.bestBatchParams.batchDelay / 1e6f);
96 
97         result.appendFormat("handle=0x%08x, active-count=%zu, batch_timeout(ms)={ ", list[i].handle,
98                             info.batchParams.size());
99         for (size_t j = 0; j < info.batchParams.size(); j++) {
100             BatchParams params = info.batchParams.valueAt(j);
101             result.appendFormat("%4.1f%s", params.batchTimeout / 1e6f,
102                                 j < info.batchParams.size() - 1 ? ", " : "");
103         }
104         result.appendFormat(" }, selected=%4.1f ms\n", info.bestBatchParams.batchTimeout / 1e6f);
105     }
106 }
107 
getSensorList(sensor_t const ** list)108 ssize_t SensorDevice::getSensorList(sensor_t const** list) {
109     if (!mSensorModule) return NO_INIT;
110     ssize_t count = mSensorModule->get_sensors_list(mSensorModule, list);
111     return count;
112 }
113 
initCheck() const114 status_t SensorDevice::initCheck() const {
115     return mSensorDevice && mSensorModule ? NO_ERROR : NO_INIT;
116 }
117 
poll(sensors_event_t * buffer,size_t count)118 ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
119     if (!mSensorDevice) return NO_INIT;
120     ssize_t c;
121     do {
122         c = mSensorDevice->poll(reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice),
123                                 buffer, count);
124     } while (c == -EINTR);
125     return c;
126 }
127 
autoDisable(void * ident,int handle)128 void SensorDevice::autoDisable(void *ident, int handle) {
129     Info& info( mActivationCount.editValueFor(handle) );
130     Mutex::Autolock _l(mLock);
131     info.removeBatchParamsForIdent(ident);
132 }
133 
activate(void * ident,int handle,int enabled)134 status_t SensorDevice::activate(void* ident, int handle, int enabled)
135 {
136     if (!mSensorDevice) return NO_INIT;
137     status_t err(NO_ERROR);
138     bool actuateHardware = false;
139 
140     Mutex::Autolock _l(mLock);
141     Info& info( mActivationCount.editValueFor(handle) );
142 
143     ALOGD_IF(DEBUG_CONNECTIONS,
144              "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%zu",
145              ident, handle, enabled, info.batchParams.size());
146 
147     if (enabled) {
148         ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%zd", info.batchParams.indexOfKey(ident));
149 
150         if (info.batchParams.indexOfKey(ident) >= 0) {
151           if (info.batchParams.size() == 1) {
152               // This is the first connection, we need to activate the underlying h/w sensor.
153               actuateHardware = true;
154           }
155         } else {
156             // Log error. Every activate call should be preceded by a batch() call.
157             ALOGE("\t >>>ERROR: activate called without batch");
158         }
159     } else {
160         ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident));
161 
162         if (info.removeBatchParamsForIdent(ident) >= 0) {
163             if (info.batchParams.size() == 0) {
164                 // This is the last connection, we need to de-activate the underlying h/w sensor.
165                 actuateHardware = true;
166             } else {
167                 const int halVersion = getHalDeviceVersion();
168                 if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) {
169                     // Call batch for this sensor with the previously calculated best effort
170                     // batch_rate and timeout. One of the apps has unregistered for sensor
171                     // events, and the best effort batch parameters might have changed.
172                     ALOGD_IF(DEBUG_CONNECTIONS,
173                              "\t>>> actuating h/w batch %d %d %" PRId64 " %" PRId64, handle,
174                              info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
175                              info.bestBatchParams.batchTimeout);
176                     mSensorDevice->batch(mSensorDevice, handle,info.bestBatchParams.flags,
177                                          info.bestBatchParams.batchDelay,
178                                          info.bestBatchParams.batchTimeout);
179                 }
180             }
181         } else {
182             // sensor wasn't enabled for this ident
183         }
184     }
185 
186     if (actuateHardware) {
187         ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle, enabled);
188         err = mSensorDevice->activate(
189                 reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), handle, enabled);
190         ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
191                  strerror(-err));
192 
193         if (err != NO_ERROR && enabled) {
194             // Failure when enabling the sensor. Clean up on failure.
195             info.removeBatchParamsForIdent(ident);
196         }
197     }
198 
199     // On older devices which do not support batch, call setDelay().
200     if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1 && info.batchParams.size() > 0) {
201         ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w setDelay %d %" PRId64, handle,
202                  info.bestBatchParams.batchDelay);
203         mSensorDevice->setDelay(
204                 reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
205                 handle, info.bestBatchParams.batchDelay);
206     }
207     return err;
208 }
209 
batch(void * ident,int handle,int flags,int64_t samplingPeriodNs,int64_t maxBatchReportLatencyNs)210 status_t SensorDevice::batch(void* ident, int handle, int flags, int64_t samplingPeriodNs,
211                              int64_t maxBatchReportLatencyNs) {
212     if (!mSensorDevice) return NO_INIT;
213 
214     if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
215         samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
216     }
217 
218     const int halVersion = getHalDeviceVersion();
219     if (halVersion < SENSORS_DEVICE_API_VERSION_1_1 && maxBatchReportLatencyNs != 0) {
220         // Batch is not supported on older devices return invalid operation.
221         return INVALID_OPERATION;
222     }
223 
224     ALOGD_IF(DEBUG_CONNECTIONS,
225              "SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%" PRId64 " timeout=%" PRId64,
226              ident, handle, flags, samplingPeriodNs, maxBatchReportLatencyNs);
227 
228     Mutex::Autolock _l(mLock);
229     Info& info(mActivationCount.editValueFor(handle));
230 
231     if (info.batchParams.indexOfKey(ident) < 0) {
232         BatchParams params(flags, samplingPeriodNs, maxBatchReportLatencyNs);
233         info.batchParams.add(ident, params);
234     } else {
235         // A batch has already been called with this ident. Update the batch parameters.
236         info.setBatchParamsForIdent(ident, flags, samplingPeriodNs, maxBatchReportLatencyNs);
237     }
238 
239     BatchParams prevBestBatchParams = info.bestBatchParams;
240     // Find the minimum of all timeouts and batch_rates for this sensor.
241     info.selectBatchParams();
242 
243     ALOGD_IF(DEBUG_CONNECTIONS,
244              "\t>>> curr_period=%" PRId64 " min_period=%" PRId64
245              " curr_timeout=%" PRId64 " min_timeout=%" PRId64,
246              prevBestBatchParams.batchDelay, info.bestBatchParams.batchDelay,
247              prevBestBatchParams.batchTimeout, info.bestBatchParams.batchTimeout);
248 
249     status_t err(NO_ERROR);
250     // If the min period or min timeout has changed since the last batch call, call batch.
251     if (prevBestBatchParams != info.bestBatchParams) {
252         if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) {
253             ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH %d %d %" PRId64 " %" PRId64, handle,
254                      info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
255                      info.bestBatchParams.batchTimeout);
256             err = mSensorDevice->batch(mSensorDevice, handle, info.bestBatchParams.flags,
257                                        info.bestBatchParams.batchDelay,
258                                        info.bestBatchParams.batchTimeout);
259         } else {
260             // For older devices which do not support batch, call setDelay() after activate() is
261             // called. Some older devices may not support calling setDelay before activate(), so
262             // call setDelay in SensorDevice::activate() method.
263         }
264         if (err != NO_ERROR) {
265             ALOGE("sensor batch failed %p %d %d %" PRId64 " %" PRId64 " err=%s",
266                   mSensorDevice, handle,
267                   info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
268                   info.bestBatchParams.batchTimeout, strerror(-err));
269             info.removeBatchParamsForIdent(ident);
270         }
271     }
272     return err;
273 }
274 
setDelay(void * ident,int handle,int64_t samplingPeriodNs)275 status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs)
276 {
277     if (!mSensorDevice) return NO_INIT;
278     if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
279         samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
280     }
281     Mutex::Autolock _l(mLock);
282     Info& info( mActivationCount.editValueFor(handle) );
283     // If the underlying sensor is NOT in continuous mode, setDelay() should return an error.
284     // Calling setDelay() in batch mode is an invalid operation.
285     if (info.bestBatchParams.batchTimeout != 0) {
286       return INVALID_OPERATION;
287     }
288     ssize_t index = info.batchParams.indexOfKey(ident);
289     if (index < 0) {
290         return BAD_INDEX;
291     }
292     BatchParams& params = info.batchParams.editValueAt(index);
293     params.batchDelay = samplingPeriodNs;
294     info.selectBatchParams();
295     return mSensorDevice->setDelay(reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
296                                    handle, info.bestBatchParams.batchDelay);
297 }
298 
getHalDeviceVersion() const299 int SensorDevice::getHalDeviceVersion() const {
300     if (!mSensorDevice) return -1;
301 
302     return mSensorDevice->common.version;
303 }
304 
flush(void * ident,int handle)305 status_t SensorDevice::flush(void* ident, int handle) {
306     if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1) {
307         return INVALID_OPERATION;
308     }
309     ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle);
310     return mSensorDevice->flush(mSensorDevice, handle);
311 }
312 
313 // ---------------------------------------------------------------------------
314 
setBatchParamsForIdent(void * ident,int flags,int64_t samplingPeriodNs,int64_t maxBatchReportLatencyNs)315 status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int flags,
316                                                     int64_t samplingPeriodNs,
317                                                     int64_t maxBatchReportLatencyNs) {
318     ssize_t index = batchParams.indexOfKey(ident);
319     if (index < 0) {
320         ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%" PRId64 " timeout=%" PRId64 ") failed (%s)",
321               ident, samplingPeriodNs, maxBatchReportLatencyNs, strerror(-index));
322         return BAD_INDEX;
323     }
324     BatchParams& params = batchParams.editValueAt(index);
325     params.flags = flags;
326     params.batchDelay = samplingPeriodNs;
327     params.batchTimeout = maxBatchReportLatencyNs;
328     return NO_ERROR;
329 }
330 
selectBatchParams()331 void SensorDevice::Info::selectBatchParams() {
332     BatchParams bestParams(-1, -1, -1);
333 
334     if (batchParams.size() > 0) {
335         BatchParams params = batchParams.valueAt(0);
336         bestParams = params;
337     }
338 
339     for (size_t i = 1; i < batchParams.size(); ++i) {
340         BatchParams params = batchParams.valueAt(i);
341         if (params.batchDelay < bestParams.batchDelay) {
342             bestParams.batchDelay = params.batchDelay;
343         }
344         if (params.batchTimeout < bestParams.batchTimeout) {
345             bestParams.batchTimeout = params.batchTimeout;
346         }
347     }
348     bestBatchParams = bestParams;
349 }
350 
removeBatchParamsForIdent(void * ident)351 ssize_t SensorDevice::Info::removeBatchParamsForIdent(void* ident) {
352     ssize_t idx = batchParams.removeItem(ident);
353     if (idx >= 0) {
354         selectBatchParams();
355     }
356     return idx;
357 }
358 
359 // ---------------------------------------------------------------------------
360 }; // namespace android
361 
362