SensorService.cpp revision 24d72350f321c17b0bfe1ef3fd52d4070a1c02c3
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 <sys/types.h>
19
20#include <utils/SortedVector.h>
21#include <utils/KeyedVector.h>
22#include <utils/threads.h>
23#include <utils/Atomic.h>
24#include <utils/Errors.h>
25#include <utils/RefBase.h>
26#include <utils/Singleton.h>
27#include <utils/String16.h>
28
29#include <binder/BinderService.h>
30#include <binder/IServiceManager.h>
31
32#include <gui/ISensorServer.h>
33#include <gui/ISensorEventConnection.h>
34
35#include <hardware/sensors.h>
36
37#include "SensorService.h"
38
39namespace android {
40// ---------------------------------------------------------------------------
41
42class BatteryService : public Singleton<BatteryService> {
43    static const int TRANSACTION_noteStartSensor = IBinder::FIRST_CALL_TRANSACTION + 3;
44    static const int TRANSACTION_noteStopSensor = IBinder::FIRST_CALL_TRANSACTION + 4;
45    static const String16 DESCRIPTOR;
46
47    friend class Singleton<BatteryService>;
48    sp<IBinder> mBatteryStatService;
49
50    BatteryService() {
51        const sp<IServiceManager> sm(defaultServiceManager());
52        if (sm != NULL) {
53            const String16 name("batteryinfo");
54            mBatteryStatService = sm->getService(name);
55        }
56    }
57
58    status_t noteStartSensor(int uid, int handle) {
59        Parcel data, reply;
60        data.writeInterfaceToken(DESCRIPTOR);
61        data.writeInt32(uid);
62        data.writeInt32(handle);
63        status_t err = mBatteryStatService->transact(
64                TRANSACTION_noteStartSensor, data, &reply, 0);
65        err = reply.readExceptionCode();
66        return err;
67    }
68
69    status_t noteStopSensor(int uid, int handle) {
70        Parcel data, reply;
71        data.writeInterfaceToken(DESCRIPTOR);
72        data.writeInt32(uid);
73        data.writeInt32(handle);
74        status_t err = mBatteryStatService->transact(
75                TRANSACTION_noteStopSensor, data, &reply, 0);
76        err = reply.readExceptionCode();
77        return err;
78    }
79
80public:
81    void enableSensor(int handle) {
82        if (mBatteryStatService != 0) {
83            int uid = IPCThreadState::self()->getCallingUid();
84            int64_t identity = IPCThreadState::self()->clearCallingIdentity();
85            noteStartSensor(uid, handle);
86            IPCThreadState::self()->restoreCallingIdentity(identity);
87        }
88    }
89    void disableSensor(int handle) {
90        if (mBatteryStatService != 0) {
91            int uid = IPCThreadState::self()->getCallingUid();
92            int64_t identity = IPCThreadState::self()->clearCallingIdentity();
93            noteStopSensor(uid, handle);
94            IPCThreadState::self()->restoreCallingIdentity(identity);
95        }
96    }
97};
98
99const String16 BatteryService::DESCRIPTOR("com.android.internal.app.IBatteryStats");
100
101ANDROID_SINGLETON_STATIC_INSTANCE(BatteryService)
102
103// ---------------------------------------------------------------------------
104
105// 100 events/s max
106static const nsecs_t MINIMUM_EVENT_PERIOD = ms2ns(10);
107
108SensorService::SensorService()
109    : Thread(false),
110      mSensorDevice(0),
111      mSensorModule(0),
112      mDump("android.permission.DUMP"),
113      mInitCheck(NO_INIT)
114{
115}
116
117void SensorService::onFirstRef()
118{
119    LOGD("nuSensorService starting...");
120
121    status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
122            (hw_module_t const**)&mSensorModule);
123
124    LOGE_IF(err, "couldn't load %s module (%s)",
125            SENSORS_HARDWARE_MODULE_ID, strerror(-err));
126
127    if (mSensorModule) {
128        err = sensors_open(&mSensorModule->common, &mSensorDevice);
129
130        LOGE_IF(err, "couldn't open device for module %s (%s)",
131                SENSORS_HARDWARE_MODULE_ID, strerror(-err));
132
133        sensors_event_t event;
134        memset(&event, 0, sizeof(event));
135
136        struct sensor_t const* list;
137        int count = mSensorModule->get_sensors_list(mSensorModule, &list);
138        mLastEventSeen.setCapacity(count);
139        for (int i=0 ; i<count ; i++) {
140            Sensor sensor(list + i);
141            LOGI("%s", sensor.getName().string());
142            mSensorList.add(sensor);
143            if (mSensorDevice) {
144                mSensorDevice->activate(mSensorDevice, sensor.getHandle(), 0);
145            }
146            mLastEventSeen.add(sensor.getHandle(), event);
147        }
148
149        if (mSensorDevice) {
150            run("SensorService", PRIORITY_URGENT_DISPLAY);
151            mInitCheck = NO_ERROR;
152        }
153    }
154}
155
156SensorService::~SensorService()
157{
158}
159
160status_t SensorService::dump(int fd, const Vector<String16>& args)
161{
162    const size_t SIZE = 1024;
163    char buffer[SIZE];
164    String8 result;
165    if (!mDump.checkCalling()) {
166        snprintf(buffer, SIZE, "Permission Denial: "
167                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
168                IPCThreadState::self()->getCallingPid(),
169                IPCThreadState::self()->getCallingUid());
170        result.append(buffer);
171    } else {
172        Mutex::Autolock _l(mLock);
173        snprintf(buffer, SIZE, "Sensor List:\n");
174        result.append(buffer);
175        for (size_t i=0 ; i<mSensorList.size() ; i++) {
176            const Sensor& s(mSensorList[i]);
177            const sensors_event_t& e(mLastEventSeen.valueFor(s.getHandle()));
178            snprintf(buffer, SIZE, "%s (vendor=%s, handle=%d, maxRate=%.2fHz, last=<%5.1f,%5.1f,%5.1f>)\n",
179                    s.getName().string(),
180                    s.getVendor().string(),
181                    s.getHandle(),
182                    s.getMinDelay() ? (1000000.0f / s.getMinDelay()) : 0.0f,
183                    e.data[0], e.data[1], e.data[2]);
184            result.append(buffer);
185        }
186
187        snprintf(buffer, SIZE, "%d active connections\n",
188                mActiveConnections.size());
189        result.append(buffer);
190        snprintf(buffer, SIZE, "Active sensors:\n");
191        result.append(buffer);
192        for (size_t i=0 ; i<mActiveSensors.size() ; i++) {
193            int handle = mActiveSensors.keyAt(i);
194            snprintf(buffer, SIZE, "%s (handle=%d, connections=%d)\n",
195                    getSensorName(handle).string(),
196                    handle,
197                    mActiveSensors.valueAt(i)->getNumConnections());
198            result.append(buffer);
199        }
200    }
201    write(fd, result.string(), result.size());
202    return NO_ERROR;
203}
204
205bool SensorService::threadLoop()
206{
207    LOGD("nuSensorService thread starting...");
208
209    sensors_event_t buffer[16];
210    sensors_event_t scratch[16];
211    struct sensors_poll_device_t* device = mSensorDevice;
212    ssize_t count;
213
214    do {
215        count = device->poll(device, buffer, sizeof(buffer)/sizeof(*buffer));
216        if (count<0) {
217            LOGE("sensor poll failed (%s)", strerror(-count));
218            break;
219        }
220
221        const SortedVector< wp<SensorEventConnection> > activeConnections(
222                getActiveConnections());
223
224        size_t numConnections = activeConnections.size();
225        if (numConnections) {
226            Mutex::Autolock _l(mLock);
227
228            // record the last event for each sensor
229            int32_t prev = buffer[0].sensor;
230            for (ssize_t i=1 ; i<count ; i++) {
231                // record the last event of each sensor type in this buffer
232                int32_t curr = buffer[i].sensor;
233                if (curr != prev) {
234                    mLastEventSeen.editValueFor(prev) = buffer[i-1];
235                    prev = curr;
236                }
237            }
238            mLastEventSeen.editValueFor(prev) = buffer[count-1];
239
240            for (size_t i=0 ; i<numConnections ; i++) {
241                sp<SensorEventConnection> connection(activeConnections[i].promote());
242                if (connection != 0) {
243                    connection->sendEvents(buffer, count, scratch);
244                }
245            }
246        }
247
248    } while (count >= 0 || Thread::exitPending());
249
250    LOGW("Exiting SensorService::threadLoop!");
251    return false;
252}
253
254SortedVector< wp<SensorService::SensorEventConnection> >
255SensorService::getActiveConnections() const
256{
257    Mutex::Autolock _l(mLock);
258    return mActiveConnections;
259}
260
261String8 SensorService::getSensorName(int handle) const {
262    size_t count = mSensorList.size();
263    for (size_t i=0 ; i<count ; i++) {
264        const Sensor& sensor(mSensorList[i]);
265        if (sensor.getHandle() == handle) {
266            return sensor.getName();
267        }
268    }
269    String8 result("unknown");
270    return result;
271}
272
273Vector<Sensor> SensorService::getSensorList()
274{
275    return mSensorList;
276}
277
278sp<ISensorEventConnection> SensorService::createSensorEventConnection()
279{
280    sp<SensorEventConnection> result(new SensorEventConnection(this));
281    return result;
282}
283
284void SensorService::cleanupConnection(const wp<SensorEventConnection>& connection)
285{
286    Mutex::Autolock _l(mLock);
287    size_t size = mActiveSensors.size();
288    for (size_t i=0 ; i<size ; ) {
289        SensorRecord* rec = mActiveSensors.valueAt(i);
290        if (rec && rec->removeConnection(connection)) {
291            mSensorDevice->activate(mSensorDevice, mActiveSensors.keyAt(i), 0);
292            mActiveSensors.removeItemsAt(i, 1);
293            delete rec;
294            size--;
295        } else {
296            i++;
297        }
298    }
299    mActiveConnections.remove(connection);
300}
301
302status_t SensorService::enable(const sp<SensorEventConnection>& connection,
303        int handle)
304{
305    if (mInitCheck != NO_ERROR)
306        return mInitCheck;
307
308    status_t err = NO_ERROR;
309    Mutex::Autolock _l(mLock);
310    SensorRecord* rec = mActiveSensors.valueFor(handle);
311    if (rec == 0) {
312        rec = new SensorRecord(connection);
313        mActiveSensors.add(handle, rec);
314        err = mSensorDevice->activate(mSensorDevice, handle, 1);
315        LOGE_IF(err, "Error activating sensor %d (%s)", handle, strerror(-err));
316        if (err == 0) {
317            BatteryService::getInstance().enableSensor(handle);
318        }
319    } else {
320        if (rec->addConnection(connection)) {
321            // this sensor is already activated, but we are adding a
322            // connection that uses it. Immediately send down the last
323            // known value of the requested sensor.
324            sensors_event_t scratch;
325            sensors_event_t& event(mLastEventSeen.editValueFor(handle));
326            if (event.version == sizeof(sensors_event_t)) {
327                connection->sendEvents(&event, 1);
328            }
329        }
330    }
331    if (err == NO_ERROR) {
332        // connection now active
333        if (connection->addSensor(handle)) {
334            // the sensor was added (which means it wasn't already there)
335            // so, see if this connection becomes active
336            if (mActiveConnections.indexOf(connection) < 0) {
337                mActiveConnections.add(connection);
338            }
339            // this could change the sensor event delivery speed
340            recomputeEventsPeriodLocked(handle);
341        }
342    }
343    return err;
344}
345
346status_t SensorService::disable(const sp<SensorEventConnection>& connection,
347        int handle)
348{
349    if (mInitCheck != NO_ERROR)
350        return mInitCheck;
351
352    status_t err = NO_ERROR;
353    Mutex::Autolock _l(mLock);
354    SensorRecord* rec = mActiveSensors.valueFor(handle);
355    if (rec) {
356        // see if this connection becomes inactive
357        connection->removeSensor(handle);
358        if (connection->hasAnySensor() == false) {
359            mActiveConnections.remove(connection);
360        }
361        // see if this sensor becomes inactive
362        if (rec->removeConnection(connection)) {
363            mActiveSensors.removeItem(handle);
364            delete rec;
365            err = mSensorDevice->activate(mSensorDevice, handle, 0);
366            if (err == 0) {
367                BatteryService::getInstance().disableSensor(handle);
368            }
369        }
370    }
371    if (err == NO_ERROR) {
372        recomputeEventsPeriodLocked(handle);
373    }
374    return err;
375}
376
377status_t SensorService::setEventRate(const sp<SensorEventConnection>& connection,
378        int handle, nsecs_t ns)
379{
380    if (mInitCheck != NO_ERROR)
381        return mInitCheck;
382
383    if (ns < 0)
384        return BAD_VALUE;
385
386    if (ns < MINIMUM_EVENTS_PERIOD)
387        ns = MINIMUM_EVENTS_PERIOD;
388
389    Mutex::Autolock _l(mLock);
390    status_t err = connection->setEventRateLocked(handle, ns);
391    if (err == NO_ERROR) {
392        recomputeEventsPeriodLocked(handle);
393    }
394    return err;
395}
396
397status_t SensorService::recomputeEventsPeriodLocked(int32_t handle)
398{
399    status_t err = NO_ERROR;
400    nsecs_t wanted = ms2ns(1000);
401    size_t count = mActiveConnections.size();
402    for (size_t i=0 ; i<count ; i++) {
403        sp<SensorEventConnection> connection(mActiveConnections[i].promote());
404        if (connection != NULL) {
405            nsecs_t ns = connection->getEventRateForSensor(handle);
406            if (ns) {
407                wanted = wanted < ns ? wanted : ns;
408            }
409        }
410    }
411    err = mSensorDevice->setDelay(mSensorDevice, handle, wanted);
412    return err;
413}
414
415// ---------------------------------------------------------------------------
416
417SensorService::SensorRecord::SensorRecord(
418        const sp<SensorEventConnection>& connection)
419{
420    mConnections.add(connection);
421}
422
423bool SensorService::SensorRecord::addConnection(
424        const sp<SensorEventConnection>& connection)
425{
426    if (mConnections.indexOf(connection) < 0) {
427        mConnections.add(connection);
428        return true;
429    }
430    return false;
431}
432
433bool SensorService::SensorRecord::removeConnection(
434        const wp<SensorEventConnection>& connection)
435{
436    ssize_t index = mConnections.indexOf(connection);
437    if (index >= 0) {
438        mConnections.removeItemsAt(index, 1);
439    }
440    return mConnections.size() ? false : true;
441}
442
443// ---------------------------------------------------------------------------
444
445SensorService::SensorEventConnection::SensorEventConnection(
446        const sp<SensorService>& service)
447    : mService(service), mChannel(new SensorChannel())
448{
449}
450
451SensorService::SensorEventConnection::~SensorEventConnection()
452{
453    mService->cleanupConnection(this);
454}
455
456void SensorService::SensorEventConnection::onFirstRef()
457{
458}
459
460bool SensorService::SensorEventConnection::addSensor(int32_t handle) {
461    if (mSensorInfo.indexOfKey(handle) <= 0) {
462        SensorInfo info;
463        mSensorInfo.add(handle, info);
464        return true;
465    }
466    return false;
467}
468
469bool SensorService::SensorEventConnection::removeSensor(int32_t handle) {
470    if (mSensorInfo.removeItem(handle) >= 0) {
471        return true;
472    }
473    return false;
474}
475
476bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
477    return mSensorInfo.indexOfKey(handle) >= 0;
478}
479
480bool SensorService::SensorEventConnection::hasAnySensor() const {
481    return mSensorInfo.size() ? true : false;
482}
483
484status_t SensorService::SensorEventConnection::setEventRateLocked(
485        int handle, nsecs_t ns)
486{
487    ssize_t index = mSensorInfo.indexOfKey(handle);
488    if (index >= 0) {
489        SensorInfo& info = mSensorInfo.editValueFor(handle);
490        info.ns = ns;
491        return NO_ERROR;
492    }
493    return status_t(index);
494}
495
496status_t SensorService::SensorEventConnection::sendEvents(
497        sensors_event_t const* buffer, size_t numEvents,
498        sensors_event_t* scratch)
499{
500    // filter out events not for this connection
501    size_t count = 0;
502    if (scratch) {
503        size_t i=0;
504        while (i<numEvents) {
505            const int32_t curr = buffer[i].sensor;
506            if (mSensorInfo.indexOfKey(curr) >= 0) {
507                do {
508                    scratch[count++] = buffer[i++];
509                } while ((i<numEvents) && (buffer[i].sensor == curr));
510            } else {
511                i++;
512            }
513        }
514    } else {
515        scratch = const_cast<sensors_event_t *>(buffer);
516        count = numEvents;
517    }
518
519    if (count == 0)
520        return 0;
521
522    ssize_t size = mChannel->write(scratch, count*sizeof(sensors_event_t));
523    if (size == -EAGAIN) {
524        // the destination doesn't accept events anymore, it's probably
525        // full. For now, we just drop the events on the floor.
526        LOGW("dropping %d events on the floor", count);
527        return size;
528    }
529
530    LOGE_IF(size<0, "dropping %d events on the floor (%s)",
531            count, strerror(-size));
532
533    return size < 0 ? status_t(size) : status_t(NO_ERROR);
534}
535
536sp<SensorChannel> SensorService::SensorEventConnection::getSensorChannel() const
537{
538    return mChannel;
539}
540
541status_t SensorService::SensorEventConnection::enableDisable(
542        int handle, bool enabled)
543{
544    status_t err;
545    if (enabled) {
546        err = mService->enable(this, handle);
547    } else {
548        err = mService->disable(this, handle);
549    }
550    return err;
551}
552
553status_t SensorService::SensorEventConnection::setEventRate(
554        int handle, nsecs_t ns)
555{
556    return mService->setEventRate(this, handle, ns);
557}
558
559// ---------------------------------------------------------------------------
560}; // namespace android
561
562