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