SensorService.cpp revision 724d91d778e71c8186399f4955de14b54812b3ed
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 <cutils/properties.h>
22
23#include <utils/SortedVector.h>
24#include <utils/KeyedVector.h>
25#include <utils/threads.h>
26#include <utils/Atomic.h>
27#include <utils/Errors.h>
28#include <utils/RefBase.h>
29#include <utils/Singleton.h>
30#include <utils/String16.h>
31
32#include <binder/BinderService.h>
33#include <binder/IServiceManager.h>
34#include <binder/PermissionCache.h>
35
36#include <gui/ISensorServer.h>
37#include <gui/ISensorEventConnection.h>
38#include <gui/SensorEventQueue.h>
39
40#include <hardware/sensors.h>
41#include <hardware_legacy/power.h>
42
43#include "BatteryService.h"
44#include "CorrectedGyroSensor.h"
45#include "GravitySensor.h"
46#include "LinearAccelerationSensor.h"
47#include "OrientationSensor.h"
48#include "RotationVectorSensor.h"
49#include "SensorFusion.h"
50#include "SensorService.h"
51
52namespace android {
53// ---------------------------------------------------------------------------
54
55/*
56 * Notes:
57 *
58 * - what about a gyro-corrected magnetic-field sensor?
59 * - run mag sensor from time to time to force calibration
60 * - gravity sensor length is wrong (=> drift in linear-acc sensor)
61 *
62 */
63
64const char* SensorService::WAKE_LOCK_NAME = "SensorService";
65
66SensorService::SensorService()
67    : mInitCheck(NO_INIT)
68{
69}
70
71void SensorService::onFirstRef()
72{
73    ALOGD("nuSensorService starting...");
74
75    SensorDevice& dev(SensorDevice::getInstance());
76
77    if (dev.initCheck() == NO_ERROR) {
78        sensor_t const* list;
79        ssize_t count = dev.getSensorList(&list);
80        if (count > 0) {
81            ssize_t orientationIndex = -1;
82            bool hasGyro = false;
83            uint32_t virtualSensorsNeeds =
84                    (1<<SENSOR_TYPE_GRAVITY) |
85                    (1<<SENSOR_TYPE_LINEAR_ACCELERATION) |
86                    (1<<SENSOR_TYPE_ROTATION_VECTOR);
87
88            mLastEventSeen.setCapacity(count);
89            for (ssize_t i=0 ; i<count ; i++) {
90                registerSensor( new HardwareSensor(list[i]) );
91                switch (list[i].type) {
92                    case SENSOR_TYPE_ORIENTATION:
93                        orientationIndex = i;
94                        break;
95                    case SENSOR_TYPE_GYROSCOPE:
96                    case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
97                        hasGyro = true;
98                        break;
99                    case SENSOR_TYPE_GRAVITY:
100                    case SENSOR_TYPE_LINEAR_ACCELERATION:
101                    case SENSOR_TYPE_ROTATION_VECTOR:
102                        virtualSensorsNeeds &= ~(1<<list[i].type);
103                        break;
104                }
105            }
106
107            // it's safe to instantiate the SensorFusion object here
108            // (it wants to be instantiated after h/w sensors have been
109            // registered)
110            const SensorFusion& fusion(SensorFusion::getInstance());
111
112            // build the sensor list returned to users
113            mUserSensorList = mSensorList;
114
115            if (hasGyro) {
116                Sensor aSensor;
117
118                // Add Android virtual sensors if they're not already
119                // available in the HAL
120
121                aSensor = registerVirtualSensor( new RotationVectorSensor() );
122                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
123                    mUserSensorList.add(aSensor);
124                }
125
126                aSensor = registerVirtualSensor( new GravitySensor(list, count) );
127                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) {
128                    mUserSensorList.add(aSensor);
129                }
130
131                aSensor = registerVirtualSensor( new LinearAccelerationSensor(list, count) );
132                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) {
133                    mUserSensorList.add(aSensor);
134                }
135
136                aSensor = registerVirtualSensor( new OrientationSensor() );
137                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
138                    // if we are doing our own rotation-vector, also add
139                    // the orientation sensor and remove the HAL provided one.
140                    mUserSensorList.replaceAt(aSensor, orientationIndex);
141                }
142
143                // virtual debugging sensors are not added to mUserSensorList
144                registerVirtualSensor( new CorrectedGyroSensor(list, count) );
145                registerVirtualSensor( new GyroDriftSensor() );
146            }
147
148            // debugging sensor list
149            mUserSensorListDebug = mSensorList;
150
151            run("SensorService", PRIORITY_URGENT_DISPLAY);
152            mInitCheck = NO_ERROR;
153        }
154    }
155}
156
157Sensor SensorService::registerSensor(SensorInterface* s)
158{
159    sensors_event_t event;
160    memset(&event, 0, sizeof(event));
161
162    const Sensor sensor(s->getSensor());
163    // add to the sensor list (returned to clients)
164    mSensorList.add(sensor);
165    // add to our handle->SensorInterface mapping
166    mSensorMap.add(sensor.getHandle(), s);
167    // create an entry in the mLastEventSeen array
168    mLastEventSeen.add(sensor.getHandle(), event);
169
170    return sensor;
171}
172
173Sensor SensorService::registerVirtualSensor(SensorInterface* s)
174{
175    Sensor sensor = registerSensor(s);
176    mVirtualSensorList.add( s );
177    return sensor;
178}
179
180SensorService::~SensorService()
181{
182    for (size_t i=0 ; i<mSensorMap.size() ; i++)
183        delete mSensorMap.valueAt(i);
184}
185
186static const String16 sDump("android.permission.DUMP");
187
188status_t SensorService::dump(int fd, const Vector<String16>& args)
189{
190    String8 result;
191    if (!PermissionCache::checkCallingPermission(sDump)) {
192        result.appendFormat("Permission Denial: "
193                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
194                IPCThreadState::self()->getCallingPid(),
195                IPCThreadState::self()->getCallingUid());
196    } else {
197        Mutex::Autolock _l(mLock);
198        result.append("Sensor List:\n");
199        for (size_t i=0 ; i<mSensorList.size() ; i++) {
200            const Sensor& s(mSensorList[i]);
201            const sensors_event_t& e(mLastEventSeen.valueFor(s.getHandle()));
202            result.appendFormat(
203                    "%-48s| %-32s | 0x%08x | ",
204                    s.getName().string(),
205                    s.getVendor().string(),
206                    s.getHandle());
207
208            if (s.getMinDelay() > 0) {
209                result.appendFormat(
210                    "maxRate=%7.2fHz | ", 1e6f / s.getMinDelay());
211            } else {
212                result.append(s.getMinDelay() == 0
213                        ? "on-demand         | "
214                        : "one-shot          | ");
215            }
216            if (s.getFifoMaxEventCount() > 0) {
217                result.appendFormat("getFifoMaxEventCount=%d events | ", s.getFifoMaxEventCount());
218            } else {
219                result.append("no batching support | ");
220            }
221
222            switch (s.getType()) {
223                case SENSOR_TYPE_ROTATION_VECTOR:
224                case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
225                    result.appendFormat(
226                            "last=<%5.1f,%5.1f,%5.1f,%5.1f,%5.1f>\n",
227                            e.data[0], e.data[1], e.data[2], e.data[3], e.data[4]);
228                    break;
229                case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
230                case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
231                    result.appendFormat(
232                            "last=<%5.1f,%5.1f,%5.1f,%5.1f,%5.1f,%5.1f>\n",
233                            e.data[0], e.data[1], e.data[2], e.data[3], e.data[4], e.data[5]);
234                    break;
235                case SENSOR_TYPE_GAME_ROTATION_VECTOR:
236                    result.appendFormat(
237                            "last=<%5.1f,%5.1f,%5.1f,%5.1f>\n",
238                            e.data[0], e.data[1], e.data[2], e.data[3]);
239                    break;
240                case SENSOR_TYPE_SIGNIFICANT_MOTION:
241                case SENSOR_TYPE_STEP_DETECTOR:
242                    result.appendFormat( "last=<%f>\n", e.data[0]);
243                    break;
244                case SENSOR_TYPE_STEP_COUNTER:
245                    result.appendFormat( "last=<%llu>\n", e.u64.step_counter);
246                    break;
247                default:
248                    // default to 3 values
249                    result.appendFormat(
250                            "last=<%5.1f,%5.1f,%5.1f>\n",
251                            e.data[0], e.data[1], e.data[2]);
252                    break;
253            }
254        }
255        SensorFusion::getInstance().dump(result);
256        SensorDevice::getInstance().dump(result);
257
258        result.appendFormat("%d active connections\n", mActiveConnections.size());
259        result.append("Active sensors:\n");
260        for (size_t i=0 ; i<mActiveSensors.size() ; i++) {
261            int handle = mActiveSensors.keyAt(i);
262            result.appendFormat("%s (handle=0x%08x, connections=%d)\n",
263                    getSensorName(handle).string(),
264                    handle,
265                    mActiveSensors.valueAt(i)->getNumConnections());
266        }
267    }
268    write(fd, result.string(), result.size());
269    return NO_ERROR;
270}
271
272void SensorService::cleanupAutoDisabledSensor(const sp<SensorEventConnection>& connection,
273        sensors_event_t const* buffer, const int count) {
274    SensorInterface* sensor;
275    status_t err = NO_ERROR;
276    for (int i=0 ; i<count ; i++) {
277        int handle = buffer[i].sensor;
278        int type = buffer[i].type;
279        if (type == SENSOR_TYPE_SIGNIFICANT_MOTION) {
280            if (connection->hasSensor(handle)) {
281                sensor = mSensorMap.valueFor(handle);
282                if (sensor != NULL) {
283                    sensor->autoDisable(connection.get(), handle);
284                }
285                cleanupWithoutDisable(connection, handle);
286            }
287        }
288    }
289}
290
291bool SensorService::threadLoop()
292{
293    ALOGD("nuSensorService thread starting...");
294
295    const size_t numEventMax = 16;
296    const size_t minBufferSize = numEventMax + numEventMax * mVirtualSensorList.size();
297    sensors_event_t buffer[minBufferSize];
298    sensors_event_t scratch[minBufferSize];
299    SensorDevice& device(SensorDevice::getInstance());
300    const size_t vcount = mVirtualSensorList.size();
301
302    ssize_t count;
303    bool wakeLockAcquired = false;
304    const int halVersion = device.getHalDeviceVersion();
305    do {
306        count = device.poll(buffer, numEventMax);
307        if (count<0) {
308            ALOGE("sensor poll failed (%s)", strerror(-count));
309            break;
310        }
311
312        // Poll has returned. Hold a wakelock.
313        // Todo(): add a flag to the sensors definitions to indicate
314        // the sensors which can wake up the AP
315        for (int i = 0; i < count; i++) {
316            if (buffer[i].type == SENSOR_TYPE_SIGNIFICANT_MOTION) {
317                 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
318                 wakeLockAcquired = true;
319                 break;
320            }
321        }
322
323        recordLastValue(buffer, count);
324
325        // handle virtual sensors
326        if (count && vcount) {
327            sensors_event_t const * const event = buffer;
328            const DefaultKeyedVector<int, SensorInterface*> virtualSensors(
329                    getActiveVirtualSensors());
330            const size_t activeVirtualSensorCount = virtualSensors.size();
331            if (activeVirtualSensorCount) {
332                size_t k = 0;
333                SensorFusion& fusion(SensorFusion::getInstance());
334                if (fusion.isEnabled()) {
335                    for (size_t i=0 ; i<size_t(count) ; i++) {
336                        fusion.process(event[i]);
337                    }
338                }
339                for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) {
340                    for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {
341                        if (count + k >= minBufferSize) {
342                            ALOGE("buffer too small to hold all events: "
343                                    "count=%u, k=%u, size=%u",
344                                    count, k, minBufferSize);
345                            break;
346                        }
347                        sensors_event_t out;
348                        SensorInterface* si = virtualSensors.valueAt(j);
349                        if (si->process(&out, event[i])) {
350                            buffer[count + k] = out;
351                            k++;
352                        }
353                    }
354                }
355                if (k) {
356                    // record the last synthesized values
357                    recordLastValue(&buffer[count], k);
358                    count += k;
359                    // sort the buffer by time-stamps
360                    sortEventBuffer(buffer, count);
361                }
362            }
363        }
364
365        // handle backward compatibility for RotationVector sensor
366        if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) {
367            for (int i = 0; i < count; i++) {
368                if (buffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) {
369                    // All the 4 components of the quaternion should be available
370                    // No heading accuracy. Set it to -1
371                    buffer[i].data[4] = -1;
372                }
373            }
374        }
375
376        // send our events to clients...
377        const SortedVector< wp<SensorEventConnection> > activeConnections(
378                getActiveConnections());
379        size_t numConnections = activeConnections.size();
380        for (size_t i=0 ; i<numConnections ; i++) {
381            sp<SensorEventConnection> connection(
382                    activeConnections[i].promote());
383            if (connection != 0) {
384                connection->sendEvents(buffer, count, scratch);
385                // Some sensors need to be auto disabled after the trigger
386                cleanupAutoDisabledSensor(connection, buffer, count);
387            }
388        }
389
390        // We have read the data, upper layers should hold the wakelock.
391        if (wakeLockAcquired) release_wake_lock(WAKE_LOCK_NAME);
392    } while (count >= 0 || Thread::exitPending());
393
394    ALOGW("Exiting SensorService::threadLoop => aborting...");
395    abort();
396    return false;
397}
398
399void SensorService::recordLastValue(
400        sensors_event_t const * buffer, size_t count)
401{
402    Mutex::Autolock _l(mLock);
403
404    // record the last event for each sensor
405    int32_t prev = buffer[0].sensor;
406    for (size_t i=1 ; i<count ; i++) {
407        // record the last event of each sensor type in this buffer
408        int32_t curr = buffer[i].sensor;
409        if (curr != prev) {
410            mLastEventSeen.editValueFor(prev) = buffer[i-1];
411            prev = curr;
412        }
413    }
414    mLastEventSeen.editValueFor(prev) = buffer[count-1];
415}
416
417void SensorService::sortEventBuffer(sensors_event_t* buffer, size_t count)
418{
419    struct compar {
420        static int cmp(void const* lhs, void const* rhs) {
421            sensors_event_t const* l = static_cast<sensors_event_t const*>(lhs);
422            sensors_event_t const* r = static_cast<sensors_event_t const*>(rhs);
423            return l->timestamp - r->timestamp;
424        }
425    };
426    qsort(buffer, count, sizeof(sensors_event_t), compar::cmp);
427}
428
429SortedVector< wp<SensorService::SensorEventConnection> >
430SensorService::getActiveConnections() const
431{
432    Mutex::Autolock _l(mLock);
433    return mActiveConnections;
434}
435
436DefaultKeyedVector<int, SensorInterface*>
437SensorService::getActiveVirtualSensors() const
438{
439    Mutex::Autolock _l(mLock);
440    return mActiveVirtualSensors;
441}
442
443String8 SensorService::getSensorName(int handle) const {
444    size_t count = mUserSensorList.size();
445    for (size_t i=0 ; i<count ; i++) {
446        const Sensor& sensor(mUserSensorList[i]);
447        if (sensor.getHandle() == handle) {
448            return sensor.getName();
449        }
450    }
451    String8 result("unknown");
452    return result;
453}
454
455Vector<Sensor> SensorService::getSensorList()
456{
457    char value[PROPERTY_VALUE_MAX];
458    property_get("debug.sensors", value, "0");
459    if (atoi(value)) {
460        return mUserSensorListDebug;
461    }
462    return mUserSensorList;
463}
464
465sp<ISensorEventConnection> SensorService::createSensorEventConnection()
466{
467    uid_t uid = IPCThreadState::self()->getCallingUid();
468    sp<SensorEventConnection> result(new SensorEventConnection(this, uid));
469    return result;
470}
471
472void SensorService::cleanupConnection(SensorEventConnection* c)
473{
474    Mutex::Autolock _l(mLock);
475    const wp<SensorEventConnection> connection(c);
476    size_t size = mActiveSensors.size();
477    ALOGD_IF(DEBUG_CONNECTIONS, "%d active sensors", size);
478    for (size_t i=0 ; i<size ; ) {
479        int handle = mActiveSensors.keyAt(i);
480        if (c->hasSensor(handle)) {
481            ALOGD_IF(DEBUG_CONNECTIONS, "%i: disabling handle=0x%08x", i, handle);
482            SensorInterface* sensor = mSensorMap.valueFor( handle );
483            ALOGE_IF(!sensor, "mSensorMap[handle=0x%08x] is null!", handle);
484            if (sensor) {
485                sensor->activate(c, false);
486            }
487        }
488        SensorRecord* rec = mActiveSensors.valueAt(i);
489        ALOGE_IF(!rec, "mActiveSensors[%d] is null (handle=0x%08x)!", i, handle);
490        ALOGD_IF(DEBUG_CONNECTIONS,
491                "removing connection %p for sensor[%d].handle=0x%08x",
492                c, i, handle);
493
494        if (rec && rec->removeConnection(connection)) {
495            ALOGD_IF(DEBUG_CONNECTIONS, "... and it was the last connection");
496            mActiveSensors.removeItemsAt(i, 1);
497            mActiveVirtualSensors.removeItem(handle);
498            delete rec;
499            size--;
500        } else {
501            i++;
502        }
503    }
504    mActiveConnections.remove(connection);
505    BatteryService::cleanup(c->getUid());
506}
507
508status_t SensorService::enable(const sp<SensorEventConnection>& connection,
509        int handle, nsecs_t samplingPeriodNs,  nsecs_t maxBatchReportLatencyNs, int reservedFlags)
510{
511    if (mInitCheck != NO_ERROR)
512        return mInitCheck;
513
514    SensorInterface* sensor = mSensorMap.valueFor(handle);
515    if (sensor == NULL) {
516        return BAD_VALUE;
517    }
518    Mutex::Autolock _l(mLock);
519    SensorRecord* rec = mActiveSensors.valueFor(handle);
520    if (rec == 0) {
521        rec = new SensorRecord(connection);
522        mActiveSensors.add(handle, rec);
523        if (sensor->isVirtual()) {
524            mActiveVirtualSensors.add(handle, sensor);
525        }
526    } else {
527        if (rec->addConnection(connection)) {
528            // this sensor is already activated, but we are adding a
529            // connection that uses it. Immediately send down the last
530            // known value of the requested sensor if it's not a
531            // "continuous" sensor.
532            if (sensor->getSensor().getMinDelay() == 0) {
533                sensors_event_t scratch;
534                sensors_event_t& event(mLastEventSeen.editValueFor(handle));
535                if (event.version == sizeof(sensors_event_t)) {
536                    connection->sendEvents(&event, 1);
537                }
538            }
539        }
540    }
541
542    if (connection->addSensor(handle)) {
543        BatteryService::enableSensor(connection->getUid(), handle);
544        // the sensor was added (which means it wasn't already there)
545        // so, see if this connection becomes active
546        if (mActiveConnections.indexOf(connection) < 0) {
547            mActiveConnections.add(connection);
548        }
549    } else {
550        ALOGW("sensor %08x already enabled in connection %p (ignoring)",
551            handle, connection.get());
552    }
553
554    nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
555    if (samplingPeriodNs < minDelayNs) {
556        samplingPeriodNs = minDelayNs;
557    }
558
559    ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d rate=%lld timeout== %lld",
560             handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs);
561
562    status_t err = sensor->batch(connection.get(), handle, reservedFlags, samplingPeriodNs,
563                                 maxBatchReportLatencyNs);
564
565    if (err == NO_ERROR) {
566        ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle);
567        err = sensor->activate(connection.get(), true);
568    }
569
570    if (err != NO_ERROR) {
571        // batch/activate has failed, reset our state.
572        cleanupWithoutDisableLocked(connection, handle);
573    }
574    return err;
575}
576
577status_t SensorService::disable(const sp<SensorEventConnection>& connection,
578        int handle)
579{
580    if (mInitCheck != NO_ERROR)
581        return mInitCheck;
582
583    Mutex::Autolock _l(mLock);
584    status_t err = cleanupWithoutDisableLocked(connection, handle);
585    if (err == NO_ERROR) {
586        SensorInterface* sensor = mSensorMap.valueFor(handle);
587        err = sensor ? sensor->activate(connection.get(), false) : status_t(BAD_VALUE);
588    }
589    return err;
590}
591
592status_t SensorService::cleanupWithoutDisable(
593        const sp<SensorEventConnection>& connection, int handle) {
594    Mutex::Autolock _l(mLock);
595    return cleanupWithoutDisableLocked(connection, handle);
596}
597
598status_t SensorService::cleanupWithoutDisableLocked(
599        const sp<SensorEventConnection>& connection, int handle) {
600    SensorRecord* rec = mActiveSensors.valueFor(handle);
601    if (rec) {
602        // see if this connection becomes inactive
603        if (connection->removeSensor(handle)) {
604            BatteryService::disableSensor(connection->getUid(), handle);
605        }
606        if (connection->hasAnySensor() == false) {
607            mActiveConnections.remove(connection);
608        }
609        // see if this sensor becomes inactive
610        if (rec->removeConnection(connection)) {
611            mActiveSensors.removeItem(handle);
612            mActiveVirtualSensors.removeItem(handle);
613            delete rec;
614        }
615        return NO_ERROR;
616    }
617    return BAD_VALUE;
618}
619
620status_t SensorService::setEventRate(const sp<SensorEventConnection>& connection,
621        int handle, nsecs_t ns)
622{
623    if (mInitCheck != NO_ERROR)
624        return mInitCheck;
625
626    SensorInterface* sensor = mSensorMap.valueFor(handle);
627    if (!sensor)
628        return BAD_VALUE;
629
630    if (ns < 0)
631        return BAD_VALUE;
632
633    nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
634    if (ns < minDelayNs) {
635        ns = minDelayNs;
636    }
637
638    return sensor->setDelay(connection.get(), handle, ns);
639}
640
641status_t SensorService::flushSensor(const sp<SensorEventConnection>& connection,
642                                    int handle) {
643  if (mInitCheck != NO_ERROR) return mInitCheck;
644  SensorInterface* sensor = mSensorMap.valueFor(handle);
645   if (sensor == NULL) {
646       return BAD_VALUE;
647  }
648  return sensor->flush(connection.get(), handle);
649}
650// ---------------------------------------------------------------------------
651
652SensorService::SensorRecord::SensorRecord(
653        const sp<SensorEventConnection>& connection)
654{
655    mConnections.add(connection);
656}
657
658bool SensorService::SensorRecord::addConnection(
659        const sp<SensorEventConnection>& connection)
660{
661    if (mConnections.indexOf(connection) < 0) {
662        mConnections.add(connection);
663        return true;
664    }
665    return false;
666}
667
668bool SensorService::SensorRecord::removeConnection(
669        const wp<SensorEventConnection>& connection)
670{
671    ssize_t index = mConnections.indexOf(connection);
672    if (index >= 0) {
673        mConnections.removeItemsAt(index, 1);
674    }
675    return mConnections.size() ? false : true;
676}
677
678// ---------------------------------------------------------------------------
679
680SensorService::SensorEventConnection::SensorEventConnection(
681        const sp<SensorService>& service, uid_t uid)
682    : mService(service), mChannel(new BitTube()), mUid(uid)
683{
684}
685
686SensorService::SensorEventConnection::~SensorEventConnection()
687{
688    ALOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this);
689    mService->cleanupConnection(this);
690}
691
692void SensorService::SensorEventConnection::onFirstRef()
693{
694}
695
696bool SensorService::SensorEventConnection::addSensor(int32_t handle) {
697    Mutex::Autolock _l(mConnectionLock);
698    if (mSensorInfo.indexOf(handle) < 0) {
699        mSensorInfo.add(handle);
700        return true;
701    }
702    return false;
703}
704
705bool SensorService::SensorEventConnection::removeSensor(int32_t handle) {
706    Mutex::Autolock _l(mConnectionLock);
707    if (mSensorInfo.remove(handle) >= 0) {
708        return true;
709    }
710    return false;
711}
712
713bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
714    Mutex::Autolock _l(mConnectionLock);
715    return mSensorInfo.indexOf(handle) >= 0;
716}
717
718bool SensorService::SensorEventConnection::hasAnySensor() const {
719    Mutex::Autolock _l(mConnectionLock);
720    return mSensorInfo.size() ? true : false;
721}
722
723status_t SensorService::SensorEventConnection::sendEvents(
724        sensors_event_t const* buffer, size_t numEvents,
725        sensors_event_t* scratch)
726{
727    // filter out events not for this connection
728    size_t count = 0;
729    if (scratch) {
730        Mutex::Autolock _l(mConnectionLock);
731        size_t i=0;
732        while (i<numEvents) {
733            int32_t curr = buffer[i].sensor;
734            if (buffer[i].type == SENSOR_TYPE_META_DATA) {
735                ALOGD_IF(DEBUG_CONNECTIONS, "flush complete event sensor==%d ",
736                         buffer[i].meta_data.sensor);
737                // Setting curr to the correct sensor to ensure the sensor events per connection are
738                // filtered correctly. buffer[i].sensor is zero for meta_data events.
739                curr = buffer[i].meta_data.sensor;
740            }
741            if (mSensorInfo.indexOf(curr) >= 0)  {
742                do {
743                    scratch[count] = buffer[i];
744                    ++count; ++i;
745                } while ((i<numEvents) && ((buffer[i].sensor == curr) ||
746                         (buffer[i].type == SENSOR_TYPE_META_DATA  &&
747                          buffer[i].meta_data.sensor == curr)));
748            } else {
749                i++;
750            }
751        }
752    } else {
753        scratch = const_cast<sensors_event_t *>(buffer);
754        count = numEvents;
755    }
756
757    // NOTE: ASensorEvent and sensors_event_t are the same type
758    ssize_t size = SensorEventQueue::write(mChannel,
759            reinterpret_cast<ASensorEvent const*>(scratch), count);
760    if (size == -EAGAIN) {
761        // the destination doesn't accept events anymore, it's probably
762        // full. For now, we just drop the events on the floor.
763        //ALOGW("dropping %d events on the floor", count);
764        return size;
765    }
766
767    return size < 0 ? status_t(size) : status_t(NO_ERROR);
768}
769
770sp<BitTube> SensorService::SensorEventConnection::getSensorChannel() const
771{
772    return mChannel;
773}
774
775status_t SensorService::SensorEventConnection::enableDisable(
776        int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
777        int reservedFlags)
778{
779    status_t err;
780    if (enabled) {
781        err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
782                               reservedFlags);
783    } else {
784        err = mService->disable(this, handle);
785    }
786    return err;
787}
788
789status_t SensorService::SensorEventConnection::setEventRate(
790        int handle, nsecs_t samplingPeriodNs)
791{
792    return mService->setEventRate(this, handle, samplingPeriodNs);
793}
794
795status_t  SensorService::SensorEventConnection::flushSensor(int handle) {
796    return mService->flushSensor(this, handle);
797}
798// ---------------------------------------------------------------------------
799}; // namespace android
800
801