SensorService.cpp revision 9a844cf78f09953145200b4074d47589257a408c
1fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian/*
2fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * Copyright (C) 2010 The Android Open Source Project
3fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian *
4fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License");
5fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * you may not use this file except in compliance with the License.
6fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * You may obtain a copy of the License at
7fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian *
8fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian *      http://www.apache.org/licenses/LICENSE-2.0
9fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian *
10fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * Unless required by applicable law or agreed to in writing, software
11fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS,
12fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * See the License for the specific language governing permissions and
14fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * limitations under the License.
15fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian */
16fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1792dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn#include <inttypes.h>
18f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include <math.h>
1992dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn#include <stdint.h>
20fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <sys/types.h>
21fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
223301542828febc768e1df42892cfac4992c35474Mathias Agopian#include <cutils/properties.h>
233301542828febc768e1df42892cfac4992c35474Mathias Agopian
24fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <utils/SortedVector.h>
25fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <utils/KeyedVector.h>
26fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <utils/threads.h>
27fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <utils/Atomic.h>
28fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <utils/Errors.h>
29fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <utils/RefBase.h>
30451beee076cac09f817abae78a990dea108a9482Mathias Agopian#include <utils/Singleton.h>
31c4a930d1d5a432a1f302763ac55460d6e83fe7e0Mathias Agopian#include <utils/String16.h>
32fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
33fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <binder/BinderService.h>
34451beee076cac09f817abae78a990dea108a9482Mathias Agopian#include <binder/IServiceManager.h>
351cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian#include <binder/PermissionCache.h>
36fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
37fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <gui/ISensorServer.h>
38fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <gui/ISensorEventConnection.h>
39907103bf186cfdd2ed9eb3b6c36de53ade7b16f6Mathias Agopian#include <gui/SensorEventQueue.h>
40fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
41fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <hardware/sensors.h>
424342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh#include <hardware_legacy/power.h>
43fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
44787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian#include "BatteryService.h"
45984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "CorrectedGyroSensor.h"
46f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "GravitySensor.h"
47f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "LinearAccelerationSensor.h"
48984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "OrientationSensor.h"
49f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "RotationVectorSensor.h"
50984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "SensorFusion.h"
51984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "SensorService.h"
52fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
53fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopiannamespace android {
54fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// ---------------------------------------------------------------------------
55fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
563301542828febc768e1df42892cfac4992c35474Mathias Agopian/*
573301542828febc768e1df42892cfac4992c35474Mathias Agopian * Notes:
583301542828febc768e1df42892cfac4992c35474Mathias Agopian *
593301542828febc768e1df42892cfac4992c35474Mathias Agopian * - what about a gyro-corrected magnetic-field sensor?
603301542828febc768e1df42892cfac4992c35474Mathias Agopian * - run mag sensor from time to time to force calibration
613301542828febc768e1df42892cfac4992c35474Mathias Agopian * - gravity sensor length is wrong (=> drift in linear-acc sensor)
623301542828febc768e1df42892cfac4992c35474Mathias Agopian *
633301542828febc768e1df42892cfac4992c35474Mathias Agopian */
643301542828febc768e1df42892cfac4992c35474Mathias Agopian
654342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganeshconst char* SensorService::WAKE_LOCK_NAME = "SensorService";
664342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
67fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorService()
681cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian    : mInitCheck(NO_INIT)
69fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
70fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
71fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
72fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianvoid SensorService::onFirstRef()
73fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
74a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block    ALOGD("nuSensorService starting...");
7550df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
76f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    SensorDevice& dev(SensorDevice::getInstance());
77fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
78f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    if (dev.initCheck() == NO_ERROR) {
79f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        sensor_t const* list;
807b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian        ssize_t count = dev.getSensorList(&list);
817b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian        if (count > 0) {
827b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            ssize_t orientationIndex = -1;
837b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            bool hasGyro = false;
847b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            uint32_t virtualSensorsNeeds =
857b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    (1<<SENSOR_TYPE_GRAVITY) |
867b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    (1<<SENSOR_TYPE_LINEAR_ACCELERATION) |
877b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    (1<<SENSOR_TYPE_ROTATION_VECTOR);
887b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian
897b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            mLastEventSeen.setCapacity(count);
907b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            for (ssize_t i=0 ; i<count ; i++) {
917b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                registerSensor( new HardwareSensor(list[i]) );
927b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                switch (list[i].type) {
937b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_ORIENTATION:
947b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        orientationIndex = i;
957b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        break;
967b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_GYROSCOPE:
970319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
987b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        hasGyro = true;
997b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        break;
1007b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_GRAVITY:
1017b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_LINEAR_ACCELERATION:
1027b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_ROTATION_VECTOR:
1037b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        virtualSensorsNeeds &= ~(1<<list[i].type);
1047b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        break;
1057b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                }
10650df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian            }
107fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1087b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            // it's safe to instantiate the SensorFusion object here
1097b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            // (it wants to be instantiated after h/w sensors have been
1107b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            // registered)
1117b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            const SensorFusion& fusion(SensorFusion::getInstance());
1127b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian
1130319306670b0344da99efa606b6f172dde575a39Mathias Agopian            // build the sensor list returned to users
1140319306670b0344da99efa606b6f172dde575a39Mathias Agopian            mUserSensorList = mSensorList;
1150319306670b0344da99efa606b6f172dde575a39Mathias Agopian
1167b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            if (hasGyro) {
1170319306670b0344da99efa606b6f172dde575a39Mathias Agopian                Sensor aSensor;
1187b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian
1190319306670b0344da99efa606b6f172dde575a39Mathias Agopian                // Add Android virtual sensors if they're not already
1200319306670b0344da99efa606b6f172dde575a39Mathias Agopian                // available in the HAL
1217b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian
1220319306670b0344da99efa606b6f172dde575a39Mathias Agopian                aSensor = registerVirtualSensor( new RotationVectorSensor() );
1230319306670b0344da99efa606b6f172dde575a39Mathias Agopian                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
1240319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    mUserSensorList.add(aSensor);
1250319306670b0344da99efa606b6f172dde575a39Mathias Agopian                }
126f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
1270319306670b0344da99efa606b6f172dde575a39Mathias Agopian                aSensor = registerVirtualSensor( new GravitySensor(list, count) );
1280319306670b0344da99efa606b6f172dde575a39Mathias Agopian                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) {
1290319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    mUserSensorList.add(aSensor);
1300319306670b0344da99efa606b6f172dde575a39Mathias Agopian                }
13133264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian
1320319306670b0344da99efa606b6f172dde575a39Mathias Agopian                aSensor = registerVirtualSensor( new LinearAccelerationSensor(list, count) );
1330319306670b0344da99efa606b6f172dde575a39Mathias Agopian                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) {
1340319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    mUserSensorList.add(aSensor);
1350319306670b0344da99efa606b6f172dde575a39Mathias Agopian                }
13633264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian
1370319306670b0344da99efa606b6f172dde575a39Mathias Agopian                aSensor = registerVirtualSensor( new OrientationSensor() );
1380319306670b0344da99efa606b6f172dde575a39Mathias Agopian                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
1390319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    // if we are doing our own rotation-vector, also add
1400319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    // the orientation sensor and remove the HAL provided one.
1410319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    mUserSensorList.replaceAt(aSensor, orientationIndex);
1427b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                }
1430319306670b0344da99efa606b6f172dde575a39Mathias Agopian
1440319306670b0344da99efa606b6f172dde575a39Mathias Agopian                // virtual debugging sensors are not added to mUserSensorList
1450319306670b0344da99efa606b6f172dde575a39Mathias Agopian                registerVirtualSensor( new CorrectedGyroSensor(list, count) );
1460319306670b0344da99efa606b6f172dde575a39Mathias Agopian                registerVirtualSensor( new GyroDriftSensor() );
147010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian            }
148010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian
14933264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian            // debugging sensor list
1500319306670b0344da99efa606b6f172dde575a39Mathias Agopian            mUserSensorListDebug = mSensorList;
15133264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian
1524c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            mSocketBufferSize = SOCKET_BUFFER_SIZE_NON_BATCHED;
1534c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            FILE *fp = fopen("/proc/sys/net/core/wmem_max", "r");
1544c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            char line[128];
1554c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            if (fp != NULL && fgets(line, sizeof(line), fp) != NULL) {
1564c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                line[sizeof(line) - 1] = '\0';
15792dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn                sscanf(line, "%zu", &mSocketBufferSize);
1584c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                if (mSocketBufferSize > MAX_SOCKET_BUFFER_SIZE_BATCHED) {
1594c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                    mSocketBufferSize = MAX_SOCKET_BUFFER_SIZE_BATCHED;
1604c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                }
1614c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
1624c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            ALOGD("Max socket buffer size %u", mSocketBufferSize);
1634c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            if (fp) {
1644c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                fclose(fp);
1654c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
1664c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
1679a844cf78f09953145200b4074d47589257a408cAravind Akella            mWakeLockAcquired = false;
1687b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            run("SensorService", PRIORITY_URGENT_DISPLAY);
1697b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            mInitCheck = NO_ERROR;
1707b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian        }
171fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
172fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
173fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1740319306670b0344da99efa606b6f172dde575a39Mathias AgopianSensor SensorService::registerSensor(SensorInterface* s)
175f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{
176f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    sensors_event_t event;
177f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    memset(&event, 0, sizeof(event));
178f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
179f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    const Sensor sensor(s->getSensor());
180f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    // add to the sensor list (returned to clients)
181f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    mSensorList.add(sensor);
182f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    // add to our handle->SensorInterface mapping
183f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    mSensorMap.add(sensor.getHandle(), s);
184f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    // create an entry in the mLastEventSeen array
185f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    mLastEventSeen.add(sensor.getHandle(), event);
1860319306670b0344da99efa606b6f172dde575a39Mathias Agopian
1870319306670b0344da99efa606b6f172dde575a39Mathias Agopian    return sensor;
188f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
189f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
1900319306670b0344da99efa606b6f172dde575a39Mathias AgopianSensor SensorService::registerVirtualSensor(SensorInterface* s)
191f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{
1920319306670b0344da99efa606b6f172dde575a39Mathias Agopian    Sensor sensor = registerSensor(s);
193f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    mVirtualSensorList.add( s );
1940319306670b0344da99efa606b6f172dde575a39Mathias Agopian    return sensor;
195f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
196f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
197fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::~SensorService()
198fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
199f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    for (size_t i=0 ; i<mSensorMap.size() ; i++)
200f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        delete mSensorMap.valueAt(i);
201fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
202fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
2031cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopianstatic const String16 sDump("android.permission.DUMP");
2041cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian
20592dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzynstatus_t SensorService::dump(int fd, const Vector<String16>& /*args*/)
206fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
207fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    String8 result;
2081cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
209ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian        result.appendFormat("Permission Denial: "
210700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                "can't dump SensorService from pid=%d, uid=%d\n",
211fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian                IPCThreadState::self()->getCallingPid(),
212fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian                IPCThreadState::self()->getCallingUid());
213fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    } else {
214fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        Mutex::Autolock _l(mLock);
215ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian        result.append("Sensor List:\n");
2163560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        for (size_t i=0 ; i<mSensorList.size() ; i++) {
2173560fb24b668675627934356f210d84d19bf4e56Mathias Agopian            const Sensor& s(mSensorList[i]);
2183560fb24b668675627934356f210d84d19bf4e56Mathias Agopian            const sensors_event_t& e(mLastEventSeen.valueFor(s.getHandle()));
219ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            result.appendFormat(
220700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                    "%-48s| %-32s| %-48s| 0x%08x | \"%s\"\n\t",
2213560fb24b668675627934356f210d84d19bf4e56Mathias Agopian                    s.getName().string(),
2223560fb24b668675627934356f210d84d19bf4e56Mathias Agopian                    s.getVendor().string(),
223700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                    s.getStringType().string(),
224700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                    s.getHandle(),
225700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                    s.getRequiredPermission().string());
226ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian
227ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            if (s.getMinDelay() > 0) {
228ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                result.appendFormat(
229700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                        "maxRate=%7.2fHz | ", 1e6f / s.getMinDelay());
230ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            } else {
231ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                result.append(s.getMinDelay() == 0
232ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                        ? "on-demand         | "
233ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                        : "one-shot          | ");
234ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            }
235724d91d778e71c8186399f4955de14b54812b3edAravind Akella            if (s.getFifoMaxEventCount() > 0) {
236700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                result.appendFormat("FifoMax=%d events | ",
237700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                        s.getFifoMaxEventCount());
238724d91d778e71c8186399f4955de14b54812b3edAravind Akella            } else {
239724d91d778e71c8186399f4955de14b54812b3edAravind Akella                result.append("no batching support | ");
240724d91d778e71c8186399f4955de14b54812b3edAravind Akella            }
241ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian
242ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            switch (s.getType()) {
243ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_ROTATION_VECTOR:
244ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
245ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    result.appendFormat(
246ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                            "last=<%5.1f,%5.1f,%5.1f,%5.1f,%5.1f>\n",
247ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                            e.data[0], e.data[1], e.data[2], e.data[3], e.data[4]);
248ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    break;
249ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
250ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
251ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    result.appendFormat(
252ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                            "last=<%5.1f,%5.1f,%5.1f,%5.1f,%5.1f,%5.1f>\n",
253ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                            e.data[0], e.data[1], e.data[2], e.data[3], e.data[4], e.data[5]);
254ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    break;
255ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_GAME_ROTATION_VECTOR:
256ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    result.appendFormat(
257ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                            "last=<%5.1f,%5.1f,%5.1f,%5.1f>\n",
258ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                            e.data[0], e.data[1], e.data[2], e.data[3]);
259ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    break;
260ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_SIGNIFICANT_MOTION:
261ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_STEP_DETECTOR:
262ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    result.appendFormat( "last=<%f>\n", e.data[0]);
263ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    break;
264ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_STEP_COUNTER:
26592dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn                    result.appendFormat( "last=<%" PRIu64 ">\n", e.u64.step_counter);
266ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    break;
267ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                default:
268ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    // default to 3 values
269ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    result.appendFormat(
270ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                            "last=<%5.1f,%5.1f,%5.1f>\n",
271ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                            e.data[0], e.data[1], e.data[2]);
272ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    break;
273ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            }
2743560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        }
275ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian        SensorFusion::getInstance().dump(result);
276ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian        SensorDevice::getInstance().dump(result);
277ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian
278ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian        result.append("Active sensors:\n");
279fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        for (size_t i=0 ; i<mActiveSensors.size() ; i++) {
2805d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian            int handle = mActiveSensors.keyAt(i);
28192dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn            result.appendFormat("%s (handle=0x%08x, connections=%zu)\n",
2825d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian                    getSensorName(handle).string(),
2835d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian                    handle,
284fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian                    mActiveSensors.valueAt(i)->getNumConnections());
285fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
2864c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
28792dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn        result.appendFormat("%zu Max Socket Buffer size\n", mSocketBufferSize);
2889a844cf78f09953145200b4074d47589257a408cAravind Akella        result.appendFormat("WakeLock Status: %s \n", mWakeLockAcquired ? "acquired" : "not held");
28992dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn        result.appendFormat("%zd active connections\n", mActiveConnections.size());
2904c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
2914c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        for (size_t i=0 ; i < mActiveConnections.size() ; i++) {
2924c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            sp<SensorEventConnection> connection(mActiveConnections[i].promote());
2934c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            if (connection != 0) {
29492dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn                result.appendFormat("Connection Number: %zu \n", i);
2954c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                connection->dump(result);
2964c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
2974c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
298fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
299fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    write(fd, result.string(), result.size());
300fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return NO_ERROR;
301fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
302fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
3039a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::cleanupAutoDisabledSensorLocked(const sp<SensorEventConnection>& connection,
3044342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        sensors_event_t const* buffer, const int count) {
3054c01b1ad80e084f0cd1057f89fdd1fcedf19dd96Jaikumar Ganesh    SensorInterface* sensor;
3064c01b1ad80e084f0cd1057f89fdd1fcedf19dd96Jaikumar Ganesh    status_t err = NO_ERROR;
3074342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    for (int i=0 ; i<count ; i++) {
3084342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        int handle = buffer[i].sensor;
3097438fd1a0132bc6de101e2a5f75040a119b6f29bMathias Agopian        int type = buffer[i].type;
3107438fd1a0132bc6de101e2a5f75040a119b6f29bMathias Agopian        if (type == SENSOR_TYPE_SIGNIFICANT_MOTION) {
3114342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            if (connection->hasSensor(handle)) {
3124c01b1ad80e084f0cd1057f89fdd1fcedf19dd96Jaikumar Ganesh                sensor = mSensorMap.valueFor(handle);
313ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian                if (sensor != NULL) {
314ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian                    sensor->autoDisable(connection.get(), handle);
3154c01b1ad80e084f0cd1057f89fdd1fcedf19dd96Jaikumar Ganesh                }
3169a844cf78f09953145200b4074d47589257a408cAravind Akella                cleanupWithoutDisableLocked(connection, handle);
3174342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            }
3184342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
3194342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
3204342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh}
3214342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
322fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::threadLoop()
323fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
324a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block    ALOGD("nuSensorService thread starting...");
325fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
32690ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    // each virtual sensor could generate an event per "real" event, that's why we need
32790ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    // to size numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT.
32890ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    // in practice, this is too aggressive, but guaranteed to be enough.
32990ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
33090ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    const size_t numEventMax = minBufferSize / (1 + mVirtualSensorList.size());
33190ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian
332d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian    sensors_event_t buffer[minBufferSize];
333d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian    sensors_event_t scratch[minBufferSize];
334f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    SensorDevice& device(SensorDevice::getInstance());
335f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    const size_t vcount = mVirtualSensorList.size();
336fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
337f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    ssize_t count;
3384342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    const int halVersion = device.getHalDeviceVersion();
339fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    do {
340f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        count = device.poll(buffer, numEventMax);
341fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        if (count<0) {
342f5a1230d322c14c42331d0a1536b50c87742973bSteve Block            ALOGE("sensor poll failed (%s)", strerror(-count));
343fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            break;
344fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
3459a844cf78f09953145200b4074d47589257a408cAravind Akella        Mutex::Autolock _l(mLock);
3469a844cf78f09953145200b4074d47589257a408cAravind Akella        // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The
3479a844cf78f09953145200b4074d47589257a408cAravind Akella        // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock,
3489a844cf78f09953145200b4074d47589257a408cAravind Akella        // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should
3499a844cf78f09953145200b4074d47589257a408cAravind Akella        // not be interleaved with decrementing SensorEventConnection::mWakeLockRefCount and
3509a844cf78f09953145200b4074d47589257a408cAravind Akella        // releasing the wakelock.
3519a844cf78f09953145200b4074d47589257a408cAravind Akella        bool bufferHasWakeUpEvent = false;
3524342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        for (int i = 0; i < count; i++) {
3539a844cf78f09953145200b4074d47589257a408cAravind Akella            if (isWakeUpSensorEvent(buffer[i])) {
3549a844cf78f09953145200b4074d47589257a408cAravind Akella                bufferHasWakeUpEvent = true;
3559a844cf78f09953145200b4074d47589257a408cAravind Akella                break;
3564342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            }
3574342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
3584342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
3599a844cf78f09953145200b4074d47589257a408cAravind Akella        if (bufferHasWakeUpEvent && !mWakeLockAcquired) {
3609a844cf78f09953145200b4074d47589257a408cAravind Akella            acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
3619a844cf78f09953145200b4074d47589257a408cAravind Akella            mWakeLockAcquired = true;
3629a844cf78f09953145200b4074d47589257a408cAravind Akella            ALOGD_IF(DEBUG_CONNECTIONS, "acquired wakelock %s", WAKE_LOCK_NAME);
3639a844cf78f09953145200b4074d47589257a408cAravind Akella        }
3649a844cf78f09953145200b4074d47589257a408cAravind Akella        recordLastValueLocked(buffer, count);
36594e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian
366f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        // handle virtual sensors
367f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        if (count && vcount) {
368984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian            sensors_event_t const * const event = buffer;
3699a844cf78f09953145200b4074d47589257a408cAravind Akella            const size_t activeVirtualSensorCount = mActiveVirtualSensors.size();
370f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            if (activeVirtualSensorCount) {
371f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                size_t k = 0;
372984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                SensorFusion& fusion(SensorFusion::getInstance());
373984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                if (fusion.isEnabled()) {
374984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                    for (size_t i=0 ; i<size_t(count) ; i++) {
375984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                        fusion.process(event[i]);
376984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                    }
377984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                }
378d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) {
379f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {
380d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                        if (count + k >= minBufferSize) {
381d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                            ALOGE("buffer too small to hold all events: "
382d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                                    "count=%u, k=%u, size=%u",
383d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                                    count, k, minBufferSize);
384d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                            break;
385d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                        }
386f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                        sensors_event_t out;
3879a844cf78f09953145200b4074d47589257a408cAravind Akella                        SensorInterface* si = mActiveVirtualSensors.valueAt(j);
388d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                        if (si->process(&out, event[i])) {
389f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                            buffer[count + k] = out;
390f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                            k++;
391f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                        }
392f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    }
393f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                }
394f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                if (k) {
395f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    // record the last synthesized values
3969a844cf78f09953145200b4074d47589257a408cAravind Akella                    recordLastValueLocked(&buffer[count], k);
397f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    count += k;
398f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    // sort the buffer by time-stamps
399f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    sortEventBuffer(buffer, count);
400f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                }
401f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            }
402f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        }
403f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
4044342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // handle backward compatibility for RotationVector sensor
4054342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) {
4064342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            for (int i = 0; i < count; i++) {
4077438fd1a0132bc6de101e2a5f75040a119b6f29bMathias Agopian                if (buffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) {
4084342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                    // All the 4 components of the quaternion should be available
4094342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                    // No heading accuracy. Set it to -1
4104342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                    buffer[i].data[4] = -1;
4114342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                }
4124342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            }
4134342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
4144342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
4159a844cf78f09953145200b4074d47589257a408cAravind Akella        // Send our events to clients. Check the state of wake lock for each client and release the
4169a844cf78f09953145200b4074d47589257a408cAravind Akella        // lock if none of the clients need it.
4179a844cf78f09953145200b4074d47589257a408cAravind Akella        bool needsWakeLock = false;
4189a844cf78f09953145200b4074d47589257a408cAravind Akella        for (size_t i=0 ; i < mActiveConnections.size(); i++) {
4199a844cf78f09953145200b4074d47589257a408cAravind Akella            sp<SensorEventConnection> connection(mActiveConnections[i].promote());
420f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            if (connection != 0) {
421f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                connection->sendEvents(buffer, count, scratch);
4229a844cf78f09953145200b4074d47589257a408cAravind Akella                needsWakeLock |= connection->needsWakeLock();
4234342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                // Some sensors need to be auto disabled after the trigger
4249a844cf78f09953145200b4074d47589257a408cAravind Akella                cleanupAutoDisabledSensorLocked(connection, buffer, count);
425fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            }
426fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
4274342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
4289a844cf78f09953145200b4074d47589257a408cAravind Akella        if (mWakeLockAcquired && !needsWakeLock) {
4299a844cf78f09953145200b4074d47589257a408cAravind Akella            release_wake_lock(WAKE_LOCK_NAME);
4309a844cf78f09953145200b4074d47589257a408cAravind Akella            mWakeLockAcquired = false;
4319a844cf78f09953145200b4074d47589257a408cAravind Akella            ALOGD_IF(DEBUG_CONNECTIONS, "released wakelock %s", WAKE_LOCK_NAME);
4329a844cf78f09953145200b4074d47589257a408cAravind Akella        }
433fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    } while (count >= 0 || Thread::exitPending());
434fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
4353c20fbed7f3a916ced10f2ed5a272271b7d81edeSteve Block    ALOGW("Exiting SensorService::threadLoop => aborting...");
4361a62301fc58cd2af18239b0415813461bf5fc41bMathias Agopian    abort();
437fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return false;
438fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
439fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
4409a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::recordLastValueLocked(
4414b84704b97300eff3ebfab85652e64d54149d205Aravind Akella        const sensors_event_t* buffer, size_t count) {
4424b84704b97300eff3ebfab85652e64d54149d205Aravind Akella    const sensors_event_t* last = NULL;
4434b84704b97300eff3ebfab85652e64d54149d205Aravind Akella    for (size_t i = 0; i < count; i++) {
4444b84704b97300eff3ebfab85652e64d54149d205Aravind Akella        const sensors_event_t* event = &buffer[i];
4454b84704b97300eff3ebfab85652e64d54149d205Aravind Akella        if (event->type != SENSOR_TYPE_META_DATA) {
4464b84704b97300eff3ebfab85652e64d54149d205Aravind Akella            if (last && event->sensor != last->sensor) {
4474b84704b97300eff3ebfab85652e64d54149d205Aravind Akella                mLastEventSeen.editValueFor(last->sensor) = *last;
4484b84704b97300eff3ebfab85652e64d54149d205Aravind Akella            }
4494b84704b97300eff3ebfab85652e64d54149d205Aravind Akella            last = event;
45094e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian        }
45194e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian    }
4524b84704b97300eff3ebfab85652e64d54149d205Aravind Akella    if (last) {
4534b84704b97300eff3ebfab85652e64d54149d205Aravind Akella        mLastEventSeen.editValueFor(last->sensor) = *last;
4544b84704b97300eff3ebfab85652e64d54149d205Aravind Akella    }
45594e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian}
45694e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian
457f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopianvoid SensorService::sortEventBuffer(sensors_event_t* buffer, size_t count)
458f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{
459f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    struct compar {
460f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        static int cmp(void const* lhs, void const* rhs) {
461f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            sensors_event_t const* l = static_cast<sensors_event_t const*>(lhs);
462f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            sensors_event_t const* r = static_cast<sensors_event_t const*>(rhs);
463a5c106a4f0afcf061728a1cb7c8c3b908728575dMathias Agopian            return l->timestamp - r->timestamp;
464f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        }
465f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    };
466f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    qsort(buffer, count, sizeof(sensors_event_t), compar::cmp);
467f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
468f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
4695d2707214dfb97bd8dfcc6620be36841d3c82420Mathias AgopianString8 SensorService::getSensorName(int handle) const {
470010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian    size_t count = mUserSensorList.size();
4715d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
472010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian        const Sensor& sensor(mUserSensorList[i]);
4735d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian        if (sensor.getHandle() == handle) {
4745d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian            return sensor.getName();
4755d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian        }
4765d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian    }
4775d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian    String8 result("unknown");
4785d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian    return result;
4795d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian}
4805d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian
481b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akellabool SensorService::isVirtualSensor(int handle) const {
482b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella    SensorInterface* sensor = mSensorMap.valueFor(handle);
483b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella    return sensor->isVirtual();
484b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella}
485b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella
4869a844cf78f09953145200b4074d47589257a408cAravind Akellabool SensorService::isWakeUpSensorEvent(const sensors_event_t& event) const {
4879a844cf78f09953145200b4074d47589257a408cAravind Akella    SensorInterface* sensor = mSensorMap.valueFor(event.sensor);
4889a844cf78f09953145200b4074d47589257a408cAravind Akella    return sensor->getSensor().isWakeUpSensor();
4899a844cf78f09953145200b4074d47589257a408cAravind Akella}
4909a844cf78f09953145200b4074d47589257a408cAravind Akella
491fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianVector<Sensor> SensorService::getSensorList()
492fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
49333264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian    char value[PROPERTY_VALUE_MAX];
49433264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian    property_get("debug.sensors", value, "0");
495700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    const Vector<Sensor>& initialSensorList = (atoi(value)) ?
496700180487ffec09d9df1657b018a7caadac24b75Aravind Akella            mUserSensorListDebug : mUserSensorList;
497700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    Vector<Sensor> accessibleSensorList;
498700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    for (size_t i = 0; i < initialSensorList.size(); i++) {
499700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        Sensor sensor = initialSensorList[i];
500700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        if (canAccessSensor(sensor)) {
501700180487ffec09d9df1657b018a7caadac24b75Aravind Akella            accessibleSensorList.add(sensor);
502700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        } else {
503700180487ffec09d9df1657b018a7caadac24b75Aravind Akella            String8 infoMessage;
504700180487ffec09d9df1657b018a7caadac24b75Aravind Akella            infoMessage.appendFormat(
505700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                    "Skipped sensor %s because it requires permission %s",
506700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                    sensor.getName().string(),
507700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                    sensor.getRequiredPermission().string());
508700180487ffec09d9df1657b018a7caadac24b75Aravind Akella            ALOGI(infoMessage.string());
509700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        }
51033264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian    }
511700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    return accessibleSensorList;
512fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
513fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
514fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopiansp<ISensorEventConnection> SensorService::createSensorEventConnection()
515fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
5165307d17fe33fc26eeeacd6339a9fbfe96cf56873Mathias Agopian    uid_t uid = IPCThreadState::self()->getCallingUid();
5175307d17fe33fc26eeeacd6339a9fbfe96cf56873Mathias Agopian    sp<SensorEventConnection> result(new SensorEventConnection(this, uid));
518fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return result;
519fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
520fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
521db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopianvoid SensorService::cleanupConnection(SensorEventConnection* c)
522fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
523fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    Mutex::Autolock _l(mLock);
524db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian    const wp<SensorEventConnection> connection(c);
5257c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    size_t size = mActiveSensors.size();
526a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block    ALOGD_IF(DEBUG_CONNECTIONS, "%d active sensors", size);
5277c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    for (size_t i=0 ; i<size ; ) {
528db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        int handle = mActiveSensors.keyAt(i);
529db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        if (c->hasSensor(handle)) {
530a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block            ALOGD_IF(DEBUG_CONNECTIONS, "%i: disabling handle=0x%08x", i, handle);
531f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            SensorInterface* sensor = mSensorMap.valueFor( handle );
532f5a1230d322c14c42331d0a1536b50c87742973bSteve Block            ALOGE_IF(!sensor, "mSensorMap[handle=0x%08x] is null!", handle);
533f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            if (sensor) {
534db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian                sensor->activate(c, false);
535f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            }
536db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        }
537db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        SensorRecord* rec = mActiveSensors.valueAt(i);
538f5a1230d322c14c42331d0a1536b50c87742973bSteve Block        ALOGE_IF(!rec, "mActiveSensors[%d] is null (handle=0x%08x)!", i, handle);
539a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block        ALOGD_IF(DEBUG_CONNECTIONS,
540a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian                "removing connection %p for sensor[%d].handle=0x%08x",
541a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian                c, i, handle);
542a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian
543db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        if (rec && rec->removeConnection(connection)) {
544a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block            ALOGD_IF(DEBUG_CONNECTIONS, "... and it was the last connection");
5457c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            mActiveSensors.removeItemsAt(i, 1);
546f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            mActiveVirtualSensors.removeItem(handle);
5477c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            delete rec;
5487c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            size--;
5497c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian        } else {
5507c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            i++;
551fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
552fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
5537c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    mActiveConnections.remove(connection);
554787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian    BatteryService::cleanup(c->getUid());
5559a844cf78f09953145200b4074d47589257a408cAravind Akella    if (c->needsWakeLock()) {
5569a844cf78f09953145200b4074d47589257a408cAravind Akella        checkWakeLockStateLocked();
5579a844cf78f09953145200b4074d47589257a408cAravind Akella    }
558fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
559fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
560700180487ffec09d9df1657b018a7caadac24b75Aravind AkellaSensor SensorService::getSensorFromHandle(int handle) const {
561700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    return mSensorMap.valueFor(handle)->getSensor();
562700180487ffec09d9df1657b018a7caadac24b75Aravind Akella}
563700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
564fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::enable(const sp<SensorEventConnection>& connection,
565724d91d778e71c8186399f4955de14b54812b3edAravind Akella        int handle, nsecs_t samplingPeriodNs,  nsecs_t maxBatchReportLatencyNs, int reservedFlags)
566fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
56750df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian    if (mInitCheck != NO_ERROR)
56850df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian        return mInitCheck;
56950df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
570f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    SensorInterface* sensor = mSensorMap.valueFor(handle);
571ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    if (sensor == NULL) {
572ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        return BAD_VALUE;
573ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    }
574700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
575700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    if (!verifyCanAccessSensor(sensor->getSensor(), "Tried enabling")) {
576700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return BAD_VALUE;
577700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
578700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
579ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    Mutex::Autolock _l(mLock);
5804342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    SensorRecord* rec = mActiveSensors.valueFor(handle);
5814342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (rec == 0) {
5824342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        rec = new SensorRecord(connection);
5834342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        mActiveSensors.add(handle, rec);
5844342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (sensor->isVirtual()) {
5854342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            mActiveVirtualSensors.add(handle, sensor);
5863560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        }
5874342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    } else {
5884342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (rec->addConnection(connection)) {
5899a844cf78f09953145200b4074d47589257a408cAravind Akella            // this sensor is already activated, but we are adding a connection that uses it.
5909a844cf78f09953145200b4074d47589257a408cAravind Akella            // Immediately send down the last known value of the requested sensor if it's not a
5914342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            // "continuous" sensor.
5924342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            if (sensor->getSensor().getMinDelay() == 0) {
5939a844cf78f09953145200b4074d47589257a408cAravind Akella                // NOTE: The wake_up flag of this event may get set to
5949a844cf78f09953145200b4074d47589257a408cAravind Akella                // WAKE_UP_SENSOR_EVENT_NEEDS_ACK if this is a wake_up event.
5954342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                sensors_event_t& event(mLastEventSeen.editValueFor(handle));
5964342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                if (event.version == sizeof(sensors_event_t)) {
5979a844cf78f09953145200b4074d47589257a408cAravind Akella                    if (isWakeUpSensorEvent(event) && !mWakeLockAcquired) {
5989a844cf78f09953145200b4074d47589257a408cAravind Akella                        acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
5999a844cf78f09953145200b4074d47589257a408cAravind Akella                        mWakeLockAcquired = true;
6009a844cf78f09953145200b4074d47589257a408cAravind Akella                        ALOGD_IF(DEBUG_CONNECTIONS, "acquired wakelock for on_change sensor %s",
6019a844cf78f09953145200b4074d47589257a408cAravind Akella                                                        WAKE_LOCK_NAME);
6029a844cf78f09953145200b4074d47589257a408cAravind Akella                    }
6039a844cf78f09953145200b4074d47589257a408cAravind Akella                    connection->sendEvents(&event, 1, NULL);
6049a844cf78f09953145200b4074d47589257a408cAravind Akella                    if (!connection->needsWakeLock() && mWakeLockAcquired) {
6059a844cf78f09953145200b4074d47589257a408cAravind Akella                        checkWakeLockStateLocked();
6069a844cf78f09953145200b4074d47589257a408cAravind Akella                    }
607f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                }
6087c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            }
609fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
610fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
6114342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
6124342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (connection->addSensor(handle)) {
6134342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        BatteryService::enableSensor(connection->getUid(), handle);
6144342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // the sensor was added (which means it wasn't already there)
6154342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // so, see if this connection becomes active
6164342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (mActiveConnections.indexOf(connection) < 0) {
6174342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            mActiveConnections.add(connection);
6184342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
6194342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    } else {
6204342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        ALOGW("sensor %08x already enabled in connection %p (ignoring)",
6214342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            handle, connection.get());
6224342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
6234342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
624724d91d778e71c8186399f4955de14b54812b3edAravind Akella    nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
625724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (samplingPeriodNs < minDelayNs) {
626724d91d778e71c8186399f4955de14b54812b3edAravind Akella        samplingPeriodNs = minDelayNs;
627724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
628724d91d778e71c8186399f4955de14b54812b3edAravind Akella
629724d91d778e71c8186399f4955de14b54812b3edAravind Akella    ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d rate=%lld timeout== %lld",
630724d91d778e71c8186399f4955de14b54812b3edAravind Akella             handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs);
631724d91d778e71c8186399f4955de14b54812b3edAravind Akella
632724d91d778e71c8186399f4955de14b54812b3edAravind Akella    status_t err = sensor->batch(connection.get(), handle, reservedFlags, samplingPeriodNs,
633724d91d778e71c8186399f4955de14b54812b3edAravind Akella                                 maxBatchReportLatencyNs);
6344c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    if (err == NO_ERROR) {
6354c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        connection->setFirstFlushPending(handle, true);
6364c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        status_t err_flush = sensor->flush(connection.get(), handle);
6374c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        // Flush may return error if the sensor is not activated or the underlying h/w sensor does
6384c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        // not support flush.
6394c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        if (err_flush != NO_ERROR) {
6404c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            connection->setFirstFlushPending(handle, false);
6414c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
6424c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
643724d91d778e71c8186399f4955de14b54812b3edAravind Akella
644724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (err == NO_ERROR) {
645724d91d778e71c8186399f4955de14b54812b3edAravind Akella        ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle);
646724d91d778e71c8186399f4955de14b54812b3edAravind Akella        err = sensor->activate(connection.get(), true);
647724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
648724d91d778e71c8186399f4955de14b54812b3edAravind Akella
6494342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (err != NO_ERROR) {
650724d91d778e71c8186399f4955de14b54812b3edAravind Akella        // batch/activate has failed, reset our state.
651ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        cleanupWithoutDisableLocked(connection, handle);
6524342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
653fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return err;
654fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
655fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
656fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::disable(const sp<SensorEventConnection>& connection,
657fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        int handle)
658fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
65950df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian    if (mInitCheck != NO_ERROR)
66050df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian        return mInitCheck;
66150df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
662ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    Mutex::Autolock _l(mLock);
663ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    status_t err = cleanupWithoutDisableLocked(connection, handle);
6644342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (err == NO_ERROR) {
6654342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        SensorInterface* sensor = mSensorMap.valueFor(handle);
6664342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        err = sensor ? sensor->activate(connection.get(), false) : status_t(BAD_VALUE);
6674342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
6684342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    return err;
6694342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh}
6704342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
671ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisable(
672ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        const sp<SensorEventConnection>& connection, int handle) {
673fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    Mutex::Autolock _l(mLock);
674ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    return cleanupWithoutDisableLocked(connection, handle);
675ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian}
676ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian
677ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisableLocked(
678ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        const sp<SensorEventConnection>& connection, int handle) {
679fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    SensorRecord* rec = mActiveSensors.valueFor(handle);
680fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (rec) {
681fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        // see if this connection becomes inactive
682787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian        if (connection->removeSensor(handle)) {
683787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian            BatteryService::disableSensor(connection->getUid(), handle);
684787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian        }
685fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        if (connection->hasAnySensor() == false) {
686fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            mActiveConnections.remove(connection);
687fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
688fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        // see if this sensor becomes inactive
689fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        if (rec->removeConnection(connection)) {
690fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            mActiveSensors.removeItem(handle);
691f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            mActiveVirtualSensors.removeItem(handle);
692fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            delete rec;
693fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
6944342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        return NO_ERROR;
6957c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    }
6964342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    return BAD_VALUE;
697fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
698fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
6997c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianstatus_t SensorService::setEventRate(const sp<SensorEventConnection>& connection,
700fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        int handle, nsecs_t ns)
701fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
70250df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian    if (mInitCheck != NO_ERROR)
70350df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian        return mInitCheck;
70450df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
705ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian    SensorInterface* sensor = mSensorMap.valueFor(handle);
706ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian    if (!sensor)
707ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian        return BAD_VALUE;
708ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian
709700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    if (!verifyCanAccessSensor(sensor->getSensor(), "Tried configuring")) {
710700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return BAD_VALUE;
711700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
712700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
7131cd700015318727d6d42236ab6274f1949fb08baMathias Agopian    if (ns < 0)
7141cd700015318727d6d42236ab6274f1949fb08baMathias Agopian        return BAD_VALUE;
7151cd700015318727d6d42236ab6274f1949fb08baMathias Agopian
71662569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian    nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
71762569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian    if (ns < minDelayNs) {
71862569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian        ns = minDelayNs;
719ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian    }
720ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian
721f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    return sensor->setDelay(connection.get(), handle, ns);
722fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
723fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
724724d91d778e71c8186399f4955de14b54812b3edAravind Akellastatus_t SensorService::flushSensor(const sp<SensorEventConnection>& connection,
725724d91d778e71c8186399f4955de14b54812b3edAravind Akella                                    int handle) {
726700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    if (mInitCheck != NO_ERROR) return mInitCheck;
727700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    SensorInterface* sensor = mSensorMap.valueFor(handle);
728700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    if (sensor == NULL) {
729700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return BAD_VALUE;
730700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
731700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
732700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    if (!verifyCanAccessSensor(sensor->getSensor(), "Tried flushing")) {
733700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return BAD_VALUE;
734700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
735700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
736700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    if (sensor->getSensor().getType() == SENSOR_TYPE_SIGNIFICANT_MOTION) {
737700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        ALOGE("flush called on Significant Motion sensor");
738700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return INVALID_OPERATION;
739700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
740700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    return sensor->flush(connection.get(), handle);
741700180487ffec09d9df1657b018a7caadac24b75Aravind Akella}
742700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
743700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
744700180487ffec09d9df1657b018a7caadac24b75Aravind Akellabool SensorService::canAccessSensor(const Sensor& sensor) {
745700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    String16 permissionString(sensor.getRequiredPermission());
746700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    return permissionString.size() == 0 ||
747700180487ffec09d9df1657b018a7caadac24b75Aravind Akella            PermissionCache::checkCallingPermission(permissionString);
748724d91d778e71c8186399f4955de14b54812b3edAravind Akella}
749700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
750700180487ffec09d9df1657b018a7caadac24b75Aravind Akellabool SensorService::verifyCanAccessSensor(const Sensor& sensor, const char* operation) {
751700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    if (canAccessSensor(sensor)) {
752700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return true;
753700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    } else {
754700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        String8 errorMessage;
755700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        errorMessage.appendFormat(
756700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                "%s a sensor (%s) without holding its required permission: %s",
757700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                operation,
758700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                sensor.getName().string(),
759700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                sensor.getRequiredPermission().string());
760700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return false;
761700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
762700180487ffec09d9df1657b018a7caadac24b75Aravind Akella}
763700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
7649a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockState() {
7659a844cf78f09953145200b4074d47589257a408cAravind Akella    Mutex::Autolock _l(mLock);
7669a844cf78f09953145200b4074d47589257a408cAravind Akella    checkWakeLockStateLocked();
7679a844cf78f09953145200b4074d47589257a408cAravind Akella}
7689a844cf78f09953145200b4074d47589257a408cAravind Akella
7699a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockStateLocked() {
7709a844cf78f09953145200b4074d47589257a408cAravind Akella    if (!mWakeLockAcquired) {
7719a844cf78f09953145200b4074d47589257a408cAravind Akella        return;
7729a844cf78f09953145200b4074d47589257a408cAravind Akella    }
7739a844cf78f09953145200b4074d47589257a408cAravind Akella    bool releaseLock = true;
7749a844cf78f09953145200b4074d47589257a408cAravind Akella    for (size_t i=0 ; i<mActiveConnections.size() ; i++) {
7759a844cf78f09953145200b4074d47589257a408cAravind Akella        sp<SensorEventConnection> connection(mActiveConnections[i].promote());
7769a844cf78f09953145200b4074d47589257a408cAravind Akella        if (connection != 0) {
7779a844cf78f09953145200b4074d47589257a408cAravind Akella            if (connection->needsWakeLock()) {
7789a844cf78f09953145200b4074d47589257a408cAravind Akella                releaseLock = false;
7799a844cf78f09953145200b4074d47589257a408cAravind Akella                break;
7809a844cf78f09953145200b4074d47589257a408cAravind Akella            }
7819a844cf78f09953145200b4074d47589257a408cAravind Akella        }
7829a844cf78f09953145200b4074d47589257a408cAravind Akella    }
7839a844cf78f09953145200b4074d47589257a408cAravind Akella    if (releaseLock) {
7849a844cf78f09953145200b4074d47589257a408cAravind Akella        ALOGD_IF(DEBUG_CONNECTIONS, "releasing wakelock %s", WAKE_LOCK_NAME);
7859a844cf78f09953145200b4074d47589257a408cAravind Akella        release_wake_lock(WAKE_LOCK_NAME);
7869a844cf78f09953145200b4074d47589257a408cAravind Akella        mWakeLockAcquired = false;
7879a844cf78f09953145200b4074d47589257a408cAravind Akella    }
7889a844cf78f09953145200b4074d47589257a408cAravind Akella}
789fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// ---------------------------------------------------------------------------
790fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
791fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorRecord::SensorRecord(
792fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        const sp<SensorEventConnection>& connection)
793fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
794fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    mConnections.add(connection);
795fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
796fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
7977c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianbool SensorService::SensorRecord::addConnection(
798fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        const sp<SensorEventConnection>& connection)
799fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
800fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (mConnections.indexOf(connection) < 0) {
801fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        mConnections.add(connection);
8027c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian        return true;
803fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
8047c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    return false;
805fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
806fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
807fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::SensorRecord::removeConnection(
808fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        const wp<SensorEventConnection>& connection)
809fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
810fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    ssize_t index = mConnections.indexOf(connection);
811fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (index >= 0) {
812fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        mConnections.removeItemsAt(index, 1);
813fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
814fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return mConnections.size() ? false : true;
815fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
816fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
817fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// ---------------------------------------------------------------------------
818fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
819fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorEventConnection::SensorEventConnection(
8205307d17fe33fc26eeeacd6339a9fbfe96cf56873Mathias Agopian        const sp<SensorService>& service, uid_t uid)
8219a844cf78f09953145200b4074d47589257a408cAravind Akella    : mService(service), mUid(uid), mWakeLockRefCount(0)
822fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
8234c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    const SensorDevice& device(SensorDevice::getInstance());
8244c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    if (device.getHalDeviceVersion() >= SENSORS_DEVICE_API_VERSION_1_1) {
8254c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        // Increase socket buffer size to 1MB for batching capabilities.
8264c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        mChannel = new BitTube(service->mSocketBufferSize);
8274c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    } else {
8284c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        mChannel = new BitTube(SOCKET_BUFFER_SIZE_NON_BATCHED);
8294c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
830fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
831fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
832fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorEventConnection::~SensorEventConnection()
833fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
834a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block    ALOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this);
835fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    mService->cleanupConnection(this);
836fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
837fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
838fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianvoid SensorService::SensorEventConnection::onFirstRef()
839fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
840fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
841fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
8429a844cf78f09953145200b4074d47589257a408cAravind Akellabool SensorService::SensorEventConnection::needsWakeLock() {
8439a844cf78f09953145200b4074d47589257a408cAravind Akella    Mutex::Autolock _l(mConnectionLock);
8449a844cf78f09953145200b4074d47589257a408cAravind Akella    return mWakeLockRefCount > 0;
8459a844cf78f09953145200b4074d47589257a408cAravind Akella}
8469a844cf78f09953145200b4074d47589257a408cAravind Akella
8474c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akellavoid SensorService::SensorEventConnection::dump(String8& result) {
8484c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    Mutex::Autolock _l(mConnectionLock);
8499a844cf78f09953145200b4074d47589257a408cAravind Akella    result.appendFormat("%d WakeLockRefCount\n", mWakeLockRefCount);
8504c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
8514c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        const FlushInfo& flushInfo = mSensorInfo.valueAt(i);
852eefced119bc568d773b86c34cd8bc9d9574638f6Patrick Tjin        result.appendFormat("\t %s | status: %s | pending flush events %d | uid %d\n",
8534c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                            mService->getSensorName(mSensorInfo.keyAt(i)).string(),
8544c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                            flushInfo.mFirstFlushPending ? "First flush pending" :
8554c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                                                           "active",
856eefced119bc568d773b86c34cd8bc9d9574638f6Patrick Tjin                            flushInfo.mPendingFlushEventsToSend,
857eefced119bc568d773b86c34cd8bc9d9574638f6Patrick Tjin                            mUid);
8584c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
8594c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella}
8604c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
8617c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianbool SensorService::SensorEventConnection::addSensor(int32_t handle) {
86271d7a5c289c6ef6b5fc86dd4784a075ca6470e38Mathias Agopian    Mutex::Autolock _l(mConnectionLock);
863700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    if (!verifyCanAccessSensor(mService->getSensorFromHandle(handle), "Tried adding")) {
864700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return false;
865700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
8664c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    if (mSensorInfo.indexOfKey(handle) < 0) {
8674c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        mSensorInfo.add(handle, FlushInfo());
8687c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian        return true;
869fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
8707c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    return false;
871fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
872fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
8737c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianbool SensorService::SensorEventConnection::removeSensor(int32_t handle) {
87471d7a5c289c6ef6b5fc86dd4784a075ca6470e38Mathias Agopian    Mutex::Autolock _l(mConnectionLock);
8754c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    if (mSensorInfo.removeItem(handle) >= 0) {
8767c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian        return true;
8777c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    }
8787c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    return false;
879fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
880fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
881fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
88271d7a5c289c6ef6b5fc86dd4784a075ca6470e38Mathias Agopian    Mutex::Autolock _l(mConnectionLock);
8834c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    return mSensorInfo.indexOfKey(handle) >= 0;
884fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
885fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
886fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::SensorEventConnection::hasAnySensor() const {
88771d7a5c289c6ef6b5fc86dd4784a075ca6470e38Mathias Agopian    Mutex::Autolock _l(mConnectionLock);
8887c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    return mSensorInfo.size() ? true : false;
8897c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian}
8907c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian
8914c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akellavoid SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle,
8924c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                                bool value) {
8934c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    Mutex::Autolock _l(mConnectionLock);
8944c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    ssize_t index = mSensorInfo.indexOfKey(handle);
8954c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    if (index >= 0) {
8964c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
8974c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        flushInfo.mFirstFlushPending = value;
8984c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
8994c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella}
9004c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
901fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::SensorEventConnection::sendEvents(
902cf51001dbf28e9885fcacd4048902f1c75768fe9Mathias Agopian        sensors_event_t const* buffer, size_t numEvents,
903cf51001dbf28e9885fcacd4048902f1c75768fe9Mathias Agopian        sensors_event_t* scratch)
904fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
905cf51001dbf28e9885fcacd4048902f1c75768fe9Mathias Agopian    // filter out events not for this connection
9063560fb24b668675627934356f210d84d19bf4e56Mathias Agopian    size_t count = 0;
9079a844cf78f09953145200b4074d47589257a408cAravind Akella    Mutex::Autolock _l(mConnectionLock);
9083560fb24b668675627934356f210d84d19bf4e56Mathias Agopian    if (scratch) {
9093560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        size_t i=0;
9103560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        while (i<numEvents) {
911724d91d778e71c8186399f4955de14b54812b3edAravind Akella            int32_t curr = buffer[i].sensor;
912724d91d778e71c8186399f4955de14b54812b3edAravind Akella            if (buffer[i].type == SENSOR_TYPE_META_DATA) {
913724d91d778e71c8186399f4955de14b54812b3edAravind Akella                ALOGD_IF(DEBUG_CONNECTIONS, "flush complete event sensor==%d ",
914724d91d778e71c8186399f4955de14b54812b3edAravind Akella                         buffer[i].meta_data.sensor);
915724d91d778e71c8186399f4955de14b54812b3edAravind Akella                // Setting curr to the correct sensor to ensure the sensor events per connection are
916724d91d778e71c8186399f4955de14b54812b3edAravind Akella                // filtered correctly. buffer[i].sensor is zero for meta_data events.
917724d91d778e71c8186399f4955de14b54812b3edAravind Akella                curr = buffer[i].meta_data.sensor;
918724d91d778e71c8186399f4955de14b54812b3edAravind Akella            }
9194c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            ssize_t index = mSensorInfo.indexOfKey(curr);
9204c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            if (index >= 0 && mSensorInfo[index].mFirstFlushPending == true &&
9214c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                buffer[i].type == SENSOR_TYPE_META_DATA) {
9224c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                // This is the first flush before activate is called. Events can now be sent for
9234c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                // this sensor on this connection.
9244c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                ALOGD_IF(DEBUG_CONNECTIONS, "First flush event for sensor==%d ",
9254c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                         buffer[i].meta_data.sensor);
9264c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                mSensorInfo.editValueAt(index).mFirstFlushPending = false;
9274c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
9284c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            if (index >= 0 && mSensorInfo[index].mFirstFlushPending == false)  {
9293560fb24b668675627934356f210d84d19bf4e56Mathias Agopian                do {
9304c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                    scratch[count++] = buffer[i++];
931724d91d778e71c8186399f4955de14b54812b3edAravind Akella                } while ((i<numEvents) && ((buffer[i].sensor == curr) ||
932724d91d778e71c8186399f4955de14b54812b3edAravind Akella                         (buffer[i].type == SENSOR_TYPE_META_DATA  &&
933724d91d778e71c8186399f4955de14b54812b3edAravind Akella                          buffer[i].meta_data.sensor == curr)));
9343560fb24b668675627934356f210d84d19bf4e56Mathias Agopian            } else {
9353560fb24b668675627934356f210d84d19bf4e56Mathias Agopian                i++;
9363560fb24b668675627934356f210d84d19bf4e56Mathias Agopian            }
937cf51001dbf28e9885fcacd4048902f1c75768fe9Mathias Agopian        }
9383560fb24b668675627934356f210d84d19bf4e56Mathias Agopian    } else {
9393560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        scratch = const_cast<sensors_event_t *>(buffer);
9403560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        count = numEvents;
941cf51001dbf28e9885fcacd4048902f1c75768fe9Mathias Agopian    }
942fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
9434c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    // Send pending flush events (if any) before sending events from the cache.
9444c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    {
9454c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        ASensorEvent flushCompleteEvent;
9464c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        flushCompleteEvent.type = SENSOR_TYPE_META_DATA;
9474c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        flushCompleteEvent.sensor = 0;
9484c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        // Loop through all the sensors for this connection and check if there are any pending
9494c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        // flush complete events to be sent.
9504c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        for (size_t i = 0; i < mSensorInfo.size(); ++i) {
9514c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            FlushInfo& flushInfo = mSensorInfo.editValueAt(i);
9524c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            while (flushInfo.mPendingFlushEventsToSend > 0) {
9534c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                flushCompleteEvent.meta_data.sensor = mSensorInfo.keyAt(i);
9544c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                ssize_t size = SensorEventQueue::write(mChannel, &flushCompleteEvent, 1);
9554c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                if (size < 0) {
9564c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                    // ALOGW("dropping %d events on the floor", count);
957c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella                    countFlushCompleteEventsLocked(scratch, count);
9584c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                    return size;
9594c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                }
9604c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                ALOGD_IF(DEBUG_CONNECTIONS, "sent dropped flush complete event==%d ",
9614c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                         flushCompleteEvent.meta_data.sensor);
9624c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                flushInfo.mPendingFlushEventsToSend--;
9634c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
9644c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
9654c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
9664c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
967b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella    // Early return if there are no events for this connection.
968b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella    if (count == 0) {
969b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella        return status_t(NO_ERROR);
970b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella    }
971b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella
9729a844cf78f09953145200b4074d47589257a408cAravind Akella    int numWakeUpSensorEvents = countWakeUpSensorEventsLocked(scratch, count);
973907103bf186cfdd2ed9eb3b6c36de53ade7b16f6Mathias Agopian    // NOTE: ASensorEvent and sensors_event_t are the same type
974907103bf186cfdd2ed9eb3b6c36de53ade7b16f6Mathias Agopian    ssize_t size = SensorEventQueue::write(mChannel,
975907103bf186cfdd2ed9eb3b6c36de53ade7b16f6Mathias Agopian            reinterpret_cast<ASensorEvent const*>(scratch), count);
976fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (size == -EAGAIN) {
977fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        // the destination doesn't accept events anymore, it's probably
978fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        // full. For now, we just drop the events on the floor.
9794c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        // ALOGW("dropping %d events on the floor", count);
980c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella        countFlushCompleteEventsLocked(scratch, count);
9819a844cf78f09953145200b4074d47589257a408cAravind Akella        mWakeLockRefCount -= numWakeUpSensorEvents;
982fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        return size;
983fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
9841e0b1e8491e5f6dc59faabe70cbfa942853150e0Jeff Brown    return size < 0 ? status_t(size) : status_t(NO_ERROR);
985fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
986fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
987c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akellavoid SensorService::SensorEventConnection::countFlushCompleteEventsLocked(
9884c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                sensors_event_t* scratch, const int numEventsDropped) {
9894c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    ALOGD_IF(DEBUG_CONNECTIONS, "dropping %d events ", numEventsDropped);
9904c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    // Count flushComplete events in the events that are about to the dropped. These will be sent
9914c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    // separately before the next batch of events.
9924c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    for (int j = 0; j < numEventsDropped; ++j) {
9934c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        if (scratch[j].type == SENSOR_TYPE_META_DATA) {
9944c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            FlushInfo& flushInfo = mSensorInfo.editValueFor(scratch[j].meta_data.sensor);
9954c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            flushInfo.mPendingFlushEventsToSend++;
9964c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            ALOGD_IF(DEBUG_CONNECTIONS, "increment pendingFlushCount %d",
9974c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                     flushInfo.mPendingFlushEventsToSend);
9984c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
9994c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
10004c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    return;
10014c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella}
10024c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
10039a844cf78f09953145200b4074d47589257a408cAravind Akellaint SensorService::SensorEventConnection::countWakeUpSensorEventsLocked(
10049a844cf78f09953145200b4074d47589257a408cAravind Akella                       sensors_event_t* scratch, const int count) {
10059a844cf78f09953145200b4074d47589257a408cAravind Akella    for (int i = 0; i < count; ++i) {
10069a844cf78f09953145200b4074d47589257a408cAravind Akella        if (mService->isWakeUpSensorEvent(scratch[i])) {
10079a844cf78f09953145200b4074d47589257a408cAravind Akella            scratch[i].flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
10089a844cf78f09953145200b4074d47589257a408cAravind Akella            ++mWakeLockRefCount;
10099a844cf78f09953145200b4074d47589257a408cAravind Akella            return 1;
10109a844cf78f09953145200b4074d47589257a408cAravind Akella        }
10119a844cf78f09953145200b4074d47589257a408cAravind Akella    }
10129a844cf78f09953145200b4074d47589257a408cAravind Akella    return 0;
10139a844cf78f09953145200b4074d47589257a408cAravind Akella}
10149a844cf78f09953145200b4074d47589257a408cAravind Akella
1015b3989276d17f2b083bec67b695d1078fb86c6c53Mathias Agopiansp<BitTube> SensorService::SensorEventConnection::getSensorChannel() const
1016fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
1017fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return mChannel;
1018fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1019fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1020fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::SensorEventConnection::enableDisable(
1021724d91d778e71c8186399f4955de14b54812b3edAravind Akella        int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
1022724d91d778e71c8186399f4955de14b54812b3edAravind Akella        int reservedFlags)
1023fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
1024fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    status_t err;
1025fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (enabled) {
1026724d91d778e71c8186399f4955de14b54812b3edAravind Akella        err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
1027724d91d778e71c8186399f4955de14b54812b3edAravind Akella                               reservedFlags);
1028fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    } else {
1029fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        err = mService->disable(this, handle);
1030fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
1031fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return err;
1032fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1033fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1034fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::SensorEventConnection::setEventRate(
1035724d91d778e71c8186399f4955de14b54812b3edAravind Akella        int handle, nsecs_t samplingPeriodNs)
1036fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
1037724d91d778e71c8186399f4955de14b54812b3edAravind Akella    return mService->setEventRate(this, handle, samplingPeriodNs);
1038fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1039fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1040701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akellastatus_t  SensorService::SensorEventConnection::flush() {
1041c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella    SensorDevice& dev(SensorDevice::getInstance());
1042c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella    const int halVersion = dev.getHalDeviceVersion();
1043701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella    Mutex::Autolock _l(mConnectionLock);
1044701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella    status_t err(NO_ERROR);
1045c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella    // Loop through all sensors for this connection and call flush on each of them.
1046701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
1047701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella        const int handle = mSensorInfo.keyAt(i);
1048b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella        if (halVersion < SENSORS_DEVICE_API_VERSION_1_1 || mService->isVirtualSensor(handle)) {
1049c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella            // For older devices just increment pending flush count which will send a trivial
1050c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella            // flush complete event.
1051c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella            FlushInfo& flushInfo = mSensorInfo.editValueFor(handle);
1052c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella            flushInfo.mPendingFlushEventsToSend++;
1053c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella        } else {
1054c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella            status_t err_flush = mService->flushSensor(this, handle);
1055c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella            if (err_flush != NO_ERROR) {
1056c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella                ALOGE("Flush error handle=%d %s", handle, strerror(-err_flush));
1057c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella            }
1058c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella            err = (err_flush != NO_ERROR) ? err_flush : err;
1059701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella        }
1060701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella    }
1061701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella    return err;
1062724d91d778e71c8186399f4955de14b54812b3edAravind Akella}
10634c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
10649a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::SensorEventConnection::decreaseWakeLockRefCount() {
10659a844cf78f09953145200b4074d47589257a408cAravind Akella    {
10669a844cf78f09953145200b4074d47589257a408cAravind Akella        Mutex::Autolock _l(mConnectionLock);
10679a844cf78f09953145200b4074d47589257a408cAravind Akella        --mWakeLockRefCount;
10689a844cf78f09953145200b4074d47589257a408cAravind Akella    }
10699a844cf78f09953145200b4074d47589257a408cAravind Akella    // Release the lock before calling checkWakeLockState which also needs the same connectionLock.
10709a844cf78f09953145200b4074d47589257a408cAravind Akella    if (mWakeLockRefCount == 0) {
10719a844cf78f09953145200b4074d47589257a408cAravind Akella        mService->checkWakeLockState();
10729a844cf78f09953145200b4074d47589257a408cAravind Akella    }
10739a844cf78f09953145200b4074d47589257a408cAravind Akella}
10749a844cf78f09953145200b4074d47589257a408cAravind Akella
1075fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// ---------------------------------------------------------------------------
1076fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}; // namespace android
1077fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1078