SensorService.cpp revision 0e025c5af365e45e02cb75c1d46b46c7f4cd44cb
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            if (fp) {
1634c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                fclose(fp);
1644c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
1654c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
1669a844cf78f09953145200b4074d47589257a408cAravind Akella            mWakeLockAcquired = false;
1677b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            run("SensorService", PRIORITY_URGENT_DISPLAY);
1687b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            mInitCheck = NO_ERROR;
1697b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian        }
170fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
171fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
172fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1730319306670b0344da99efa606b6f172dde575a39Mathias AgopianSensor SensorService::registerSensor(SensorInterface* s)
174f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{
175f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    sensors_event_t event;
176f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    memset(&event, 0, sizeof(event));
177f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
178f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    const Sensor sensor(s->getSensor());
179f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    // add to the sensor list (returned to clients)
180f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    mSensorList.add(sensor);
181f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    // add to our handle->SensorInterface mapping
182f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    mSensorMap.add(sensor.getHandle(), s);
183f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    // create an entry in the mLastEventSeen array
184f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    mLastEventSeen.add(sensor.getHandle(), event);
1850319306670b0344da99efa606b6f172dde575a39Mathias Agopian
1860319306670b0344da99efa606b6f172dde575a39Mathias Agopian    return sensor;
187f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
188f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
1890319306670b0344da99efa606b6f172dde575a39Mathias AgopianSensor SensorService::registerVirtualSensor(SensorInterface* s)
190f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{
1910319306670b0344da99efa606b6f172dde575a39Mathias Agopian    Sensor sensor = registerSensor(s);
192f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    mVirtualSensorList.add( s );
1930319306670b0344da99efa606b6f172dde575a39Mathias Agopian    return sensor;
194f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
195f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
196fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::~SensorService()
197fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
198f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    for (size_t i=0 ; i<mSensorMap.size() ; i++)
199f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        delete mSensorMap.valueAt(i);
200fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
201fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
2021cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopianstatic const String16 sDump("android.permission.DUMP");
2031cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian
20492dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzynstatus_t SensorService::dump(int fd, const Vector<String16>& /*args*/)
205fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
206fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    String8 result;
2071cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
208ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian        result.appendFormat("Permission Denial: "
209700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                "can't dump SensorService from pid=%d, uid=%d\n",
210fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian                IPCThreadState::self()->getCallingPid(),
211fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian                IPCThreadState::self()->getCallingUid());
212fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    } else {
213fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        Mutex::Autolock _l(mLock);
214ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian        result.append("Sensor List:\n");
2153560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        for (size_t i=0 ; i<mSensorList.size() ; i++) {
2163560fb24b668675627934356f210d84d19bf4e56Mathias Agopian            const Sensor& s(mSensorList[i]);
2173560fb24b668675627934356f210d84d19bf4e56Mathias Agopian            const sensors_event_t& e(mLastEventSeen.valueFor(s.getHandle()));
218ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            result.appendFormat(
219700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                    "%-48s| %-32s| %-48s| 0x%08x | \"%s\"\n\t",
2203560fb24b668675627934356f210d84d19bf4e56Mathias Agopian                    s.getName().string(),
2213560fb24b668675627934356f210d84d19bf4e56Mathias Agopian                    s.getVendor().string(),
222700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                    s.getStringType().string(),
223700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                    s.getHandle(),
224700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                    s.getRequiredPermission().string());
225ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian
2260e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            const int reportingMode = s.getReportingMode();
2270e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            if (reportingMode == AREPORTING_MODE_CONTINUOUS) {
2280e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella                result.append("continuous      |");
2290e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            } else if (reportingMode == AREPORTING_MODE_ON_CHANGE) {
2300e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella                result.append("on-change       | ");
2310e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            } else if (reportingMode == AREPORTING_MODE_ONE_SHOT) {
2320e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella                result.append("one-shot        | ");
2330e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            } else {
2340e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella                result.append("special-trigger | ");
2350e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            }
2360e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella
237ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            if (s.getMinDelay() > 0) {
2380e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella                result.appendFormat("maxRate=%7.2fHz | ", 1e6f / s.getMinDelay());
239ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            } else {
2400e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella                result.appendFormat("minDelay=%5dus |", s.getMinDelay());
241ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            }
2420e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella
243724d91d778e71c8186399f4955de14b54812b3edAravind Akella            if (s.getFifoMaxEventCount() > 0) {
244700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                result.appendFormat("FifoMax=%d events | ",
245700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                        s.getFifoMaxEventCount());
246724d91d778e71c8186399f4955de14b54812b3edAravind Akella            } else {
247724d91d778e71c8186399f4955de14b54812b3edAravind Akella                result.append("no batching support | ");
248724d91d778e71c8186399f4955de14b54812b3edAravind Akella            }
249ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian
250ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            switch (s.getType()) {
251ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_ROTATION_VECTOR:
252ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
253ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    result.appendFormat(
254ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                            "last=<%5.1f,%5.1f,%5.1f,%5.1f,%5.1f>\n",
255ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                            e.data[0], e.data[1], e.data[2], e.data[3], e.data[4]);
256ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    break;
257ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
258ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
259ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    result.appendFormat(
260ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                            "last=<%5.1f,%5.1f,%5.1f,%5.1f,%5.1f,%5.1f>\n",
261ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                            e.data[0], e.data[1], e.data[2], e.data[3], e.data[4], e.data[5]);
262ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    break;
263ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_GAME_ROTATION_VECTOR:
264ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    result.appendFormat(
265ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                            "last=<%5.1f,%5.1f,%5.1f,%5.1f>\n",
266ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                            e.data[0], e.data[1], e.data[2], e.data[3]);
267ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    break;
268ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_SIGNIFICANT_MOTION:
269ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_STEP_DETECTOR:
270ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    result.appendFormat( "last=<%f>\n", e.data[0]);
271ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    break;
272ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_STEP_COUNTER:
27392dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn                    result.appendFormat( "last=<%" PRIu64 ">\n", e.u64.step_counter);
274ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    break;
275ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                default:
276ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    // default to 3 values
277ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    result.appendFormat(
278ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                            "last=<%5.1f,%5.1f,%5.1f>\n",
279ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                            e.data[0], e.data[1], e.data[2]);
280ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    break;
281ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            }
2823560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        }
283ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian        SensorFusion::getInstance().dump(result);
284ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian        SensorDevice::getInstance().dump(result);
285ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian
286ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian        result.append("Active sensors:\n");
287fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        for (size_t i=0 ; i<mActiveSensors.size() ; i++) {
2885d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian            int handle = mActiveSensors.keyAt(i);
28992dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn            result.appendFormat("%s (handle=0x%08x, connections=%zu)\n",
2905d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian                    getSensorName(handle).string(),
2915d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian                    handle,
292fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian                    mActiveSensors.valueAt(i)->getNumConnections());
293fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
2944c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
29592dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn        result.appendFormat("%zu Max Socket Buffer size\n", mSocketBufferSize);
2969a844cf78f09953145200b4074d47589257a408cAravind Akella        result.appendFormat("WakeLock Status: %s \n", mWakeLockAcquired ? "acquired" : "not held");
29792dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn        result.appendFormat("%zd active connections\n", mActiveConnections.size());
2984c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
2994c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        for (size_t i=0 ; i < mActiveConnections.size() ; i++) {
3004c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            sp<SensorEventConnection> connection(mActiveConnections[i].promote());
3014c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            if (connection != 0) {
30292dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn                result.appendFormat("Connection Number: %zu \n", i);
3034c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                connection->dump(result);
3044c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
3054c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
306fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
307fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    write(fd, result.string(), result.size());
308fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return NO_ERROR;
309fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
310fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
3119a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::cleanupAutoDisabledSensorLocked(const sp<SensorEventConnection>& connection,
3124342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        sensors_event_t const* buffer, const int count) {
3134342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    for (int i=0 ; i<count ; i++) {
3144342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        int handle = buffer[i].sensor;
3150e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella        if (connection->hasSensor(handle)) {
3160e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            SensorInterface* sensor = mSensorMap.valueFor(handle);
3170e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            // If this buffer has an event from a one_shot sensor and this connection is registered
3180e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            // for this particular one_shot sensor, try cleaning up the connection.
3190e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            if (sensor != NULL &&
3200e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella                sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
3210e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella                sensor->autoDisable(connection.get(), handle);
3229a844cf78f09953145200b4074d47589257a408cAravind Akella                cleanupWithoutDisableLocked(connection, handle);
3234342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            }
3244342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
3254342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
3264342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh}
3274342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
328fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::threadLoop()
329fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
330a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block    ALOGD("nuSensorService thread starting...");
331fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
33290ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    // each virtual sensor could generate an event per "real" event, that's why we need
33390ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    // to size numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT.
33490ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    // in practice, this is too aggressive, but guaranteed to be enough.
33590ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
33690ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    const size_t numEventMax = minBufferSize / (1 + mVirtualSensorList.size());
33790ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian
338d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian    sensors_event_t buffer[minBufferSize];
339d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian    sensors_event_t scratch[minBufferSize];
340f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    SensorDevice& device(SensorDevice::getInstance());
341f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    const size_t vcount = mVirtualSensorList.size();
342fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
343f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    ssize_t count;
3444342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    const int halVersion = device.getHalDeviceVersion();
345fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    do {
346f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        count = device.poll(buffer, numEventMax);
347fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        if (count<0) {
348f5a1230d322c14c42331d0a1536b50c87742973bSteve Block            ALOGE("sensor poll failed (%s)", strerror(-count));
349fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            break;
350fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
3519a844cf78f09953145200b4074d47589257a408cAravind Akella        Mutex::Autolock _l(mLock);
3529a844cf78f09953145200b4074d47589257a408cAravind Akella        // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The
3539a844cf78f09953145200b4074d47589257a408cAravind Akella        // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock,
3549a844cf78f09953145200b4074d47589257a408cAravind Akella        // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should
3559a844cf78f09953145200b4074d47589257a408cAravind Akella        // not be interleaved with decrementing SensorEventConnection::mWakeLockRefCount and
3569a844cf78f09953145200b4074d47589257a408cAravind Akella        // releasing the wakelock.
3579a844cf78f09953145200b4074d47589257a408cAravind Akella        bool bufferHasWakeUpEvent = false;
3584342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        for (int i = 0; i < count; i++) {
3599a844cf78f09953145200b4074d47589257a408cAravind Akella            if (isWakeUpSensorEvent(buffer[i])) {
3609a844cf78f09953145200b4074d47589257a408cAravind Akella                bufferHasWakeUpEvent = true;
3619a844cf78f09953145200b4074d47589257a408cAravind Akella                break;
3624342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            }
3634342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
3644342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
3659a844cf78f09953145200b4074d47589257a408cAravind Akella        if (bufferHasWakeUpEvent && !mWakeLockAcquired) {
3669a844cf78f09953145200b4074d47589257a408cAravind Akella            acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
3679a844cf78f09953145200b4074d47589257a408cAravind Akella            mWakeLockAcquired = true;
3689a844cf78f09953145200b4074d47589257a408cAravind Akella            ALOGD_IF(DEBUG_CONNECTIONS, "acquired wakelock %s", WAKE_LOCK_NAME);
3699a844cf78f09953145200b4074d47589257a408cAravind Akella        }
3709a844cf78f09953145200b4074d47589257a408cAravind Akella        recordLastValueLocked(buffer, count);
37194e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian
372f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        // handle virtual sensors
373f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        if (count && vcount) {
374984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian            sensors_event_t const * const event = buffer;
3759a844cf78f09953145200b4074d47589257a408cAravind Akella            const size_t activeVirtualSensorCount = mActiveVirtualSensors.size();
376f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            if (activeVirtualSensorCount) {
377f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                size_t k = 0;
378984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                SensorFusion& fusion(SensorFusion::getInstance());
379984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                if (fusion.isEnabled()) {
380984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                    for (size_t i=0 ; i<size_t(count) ; i++) {
381984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                        fusion.process(event[i]);
382984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                    }
383984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                }
384d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) {
385f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {
386d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                        if (count + k >= minBufferSize) {
387d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                            ALOGE("buffer too small to hold all events: "
388d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                                    "count=%u, k=%u, size=%u",
389d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                                    count, k, minBufferSize);
390d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                            break;
391d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                        }
392f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                        sensors_event_t out;
3939a844cf78f09953145200b4074d47589257a408cAravind Akella                        SensorInterface* si = mActiveVirtualSensors.valueAt(j);
394d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                        if (si->process(&out, event[i])) {
395f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                            buffer[count + k] = out;
396f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                            k++;
397f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                        }
398f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    }
399f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                }
400f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                if (k) {
401f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    // record the last synthesized values
4029a844cf78f09953145200b4074d47589257a408cAravind Akella                    recordLastValueLocked(&buffer[count], k);
403f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    count += k;
404f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    // sort the buffer by time-stamps
405f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    sortEventBuffer(buffer, count);
406f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                }
407f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            }
408f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        }
409f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
4104342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // handle backward compatibility for RotationVector sensor
4114342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) {
4124342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            for (int i = 0; i < count; i++) {
4137438fd1a0132bc6de101e2a5f75040a119b6f29bMathias Agopian                if (buffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) {
4144342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                    // All the 4 components of the quaternion should be available
4154342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                    // No heading accuracy. Set it to -1
4164342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                    buffer[i].data[4] = -1;
4174342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                }
4184342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            }
4194342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
4204342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
4219a844cf78f09953145200b4074d47589257a408cAravind Akella        // Send our events to clients. Check the state of wake lock for each client and release the
4229a844cf78f09953145200b4074d47589257a408cAravind Akella        // lock if none of the clients need it.
4239a844cf78f09953145200b4074d47589257a408cAravind Akella        bool needsWakeLock = false;
4249a844cf78f09953145200b4074d47589257a408cAravind Akella        for (size_t i=0 ; i < mActiveConnections.size(); i++) {
4259a844cf78f09953145200b4074d47589257a408cAravind Akella            sp<SensorEventConnection> connection(mActiveConnections[i].promote());
426f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            if (connection != 0) {
427f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                connection->sendEvents(buffer, count, scratch);
4289a844cf78f09953145200b4074d47589257a408cAravind Akella                needsWakeLock |= connection->needsWakeLock();
4294342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                // Some sensors need to be auto disabled after the trigger
4309a844cf78f09953145200b4074d47589257a408cAravind Akella                cleanupAutoDisabledSensorLocked(connection, buffer, count);
431fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            }
432fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
4334342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
4349a844cf78f09953145200b4074d47589257a408cAravind Akella        if (mWakeLockAcquired && !needsWakeLock) {
4359a844cf78f09953145200b4074d47589257a408cAravind Akella            release_wake_lock(WAKE_LOCK_NAME);
4369a844cf78f09953145200b4074d47589257a408cAravind Akella            mWakeLockAcquired = false;
4379a844cf78f09953145200b4074d47589257a408cAravind Akella            ALOGD_IF(DEBUG_CONNECTIONS, "released wakelock %s", WAKE_LOCK_NAME);
4389a844cf78f09953145200b4074d47589257a408cAravind Akella        }
439fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    } while (count >= 0 || Thread::exitPending());
440fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
4413c20fbed7f3a916ced10f2ed5a272271b7d81edeSteve Block    ALOGW("Exiting SensorService::threadLoop => aborting...");
4421a62301fc58cd2af18239b0415813461bf5fc41bMathias Agopian    abort();
443fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return false;
444fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
445fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
4469a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::recordLastValueLocked(
4474b84704b97300eff3ebfab85652e64d54149d205Aravind Akella        const sensors_event_t* buffer, size_t count) {
4484b84704b97300eff3ebfab85652e64d54149d205Aravind Akella    const sensors_event_t* last = NULL;
4494b84704b97300eff3ebfab85652e64d54149d205Aravind Akella    for (size_t i = 0; i < count; i++) {
4504b84704b97300eff3ebfab85652e64d54149d205Aravind Akella        const sensors_event_t* event = &buffer[i];
4514b84704b97300eff3ebfab85652e64d54149d205Aravind Akella        if (event->type != SENSOR_TYPE_META_DATA) {
4524b84704b97300eff3ebfab85652e64d54149d205Aravind Akella            if (last && event->sensor != last->sensor) {
4534b84704b97300eff3ebfab85652e64d54149d205Aravind Akella                mLastEventSeen.editValueFor(last->sensor) = *last;
4544b84704b97300eff3ebfab85652e64d54149d205Aravind Akella            }
4554b84704b97300eff3ebfab85652e64d54149d205Aravind Akella            last = event;
45694e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian        }
45794e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian    }
4584b84704b97300eff3ebfab85652e64d54149d205Aravind Akella    if (last) {
4594b84704b97300eff3ebfab85652e64d54149d205Aravind Akella        mLastEventSeen.editValueFor(last->sensor) = *last;
4604b84704b97300eff3ebfab85652e64d54149d205Aravind Akella    }
46194e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian}
46294e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian
463f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopianvoid SensorService::sortEventBuffer(sensors_event_t* buffer, size_t count)
464f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{
465f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    struct compar {
466f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        static int cmp(void const* lhs, void const* rhs) {
467f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            sensors_event_t const* l = static_cast<sensors_event_t const*>(lhs);
468f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            sensors_event_t const* r = static_cast<sensors_event_t const*>(rhs);
469a5c106a4f0afcf061728a1cb7c8c3b908728575dMathias Agopian            return l->timestamp - r->timestamp;
470f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        }
471f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    };
472f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    qsort(buffer, count, sizeof(sensors_event_t), compar::cmp);
473f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
474f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
4755d2707214dfb97bd8dfcc6620be36841d3c82420Mathias AgopianString8 SensorService::getSensorName(int handle) const {
476010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian    size_t count = mUserSensorList.size();
4775d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
478010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian        const Sensor& sensor(mUserSensorList[i]);
4795d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian        if (sensor.getHandle() == handle) {
4805d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian            return sensor.getName();
4815d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian        }
4825d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian    }
4835d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian    String8 result("unknown");
4845d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian    return result;
4855d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian}
4865d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian
487b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akellabool SensorService::isVirtualSensor(int handle) const {
488b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella    SensorInterface* sensor = mSensorMap.valueFor(handle);
489b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella    return sensor->isVirtual();
490b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella}
491b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella
4929a844cf78f09953145200b4074d47589257a408cAravind Akellabool SensorService::isWakeUpSensorEvent(const sensors_event_t& event) const {
4939a844cf78f09953145200b4074d47589257a408cAravind Akella    SensorInterface* sensor = mSensorMap.valueFor(event.sensor);
4949a844cf78f09953145200b4074d47589257a408cAravind Akella    return sensor->getSensor().isWakeUpSensor();
4959a844cf78f09953145200b4074d47589257a408cAravind Akella}
4969a844cf78f09953145200b4074d47589257a408cAravind Akella
497fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianVector<Sensor> SensorService::getSensorList()
498fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
49933264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian    char value[PROPERTY_VALUE_MAX];
50033264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian    property_get("debug.sensors", value, "0");
501700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    const Vector<Sensor>& initialSensorList = (atoi(value)) ?
502700180487ffec09d9df1657b018a7caadac24b75Aravind Akella            mUserSensorListDebug : mUserSensorList;
503700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    Vector<Sensor> accessibleSensorList;
504700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    for (size_t i = 0; i < initialSensorList.size(); i++) {
505700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        Sensor sensor = initialSensorList[i];
506700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        if (canAccessSensor(sensor)) {
507700180487ffec09d9df1657b018a7caadac24b75Aravind Akella            accessibleSensorList.add(sensor);
508700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        } else {
509700180487ffec09d9df1657b018a7caadac24b75Aravind Akella            String8 infoMessage;
510700180487ffec09d9df1657b018a7caadac24b75Aravind Akella            infoMessage.appendFormat(
511700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                    "Skipped sensor %s because it requires permission %s",
512700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                    sensor.getName().string(),
513700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                    sensor.getRequiredPermission().string());
514700180487ffec09d9df1657b018a7caadac24b75Aravind Akella            ALOGI(infoMessage.string());
515700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        }
51633264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian    }
517700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    return accessibleSensorList;
518fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
519fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
520fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopiansp<ISensorEventConnection> SensorService::createSensorEventConnection()
521fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
5225307d17fe33fc26eeeacd6339a9fbfe96cf56873Mathias Agopian    uid_t uid = IPCThreadState::self()->getCallingUid();
5235307d17fe33fc26eeeacd6339a9fbfe96cf56873Mathias Agopian    sp<SensorEventConnection> result(new SensorEventConnection(this, uid));
524fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return result;
525fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
526fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
527db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopianvoid SensorService::cleanupConnection(SensorEventConnection* c)
528fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
529fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    Mutex::Autolock _l(mLock);
530db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian    const wp<SensorEventConnection> connection(c);
5317c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    size_t size = mActiveSensors.size();
532a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block    ALOGD_IF(DEBUG_CONNECTIONS, "%d active sensors", size);
5337c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    for (size_t i=0 ; i<size ; ) {
534db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        int handle = mActiveSensors.keyAt(i);
535db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        if (c->hasSensor(handle)) {
536a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block            ALOGD_IF(DEBUG_CONNECTIONS, "%i: disabling handle=0x%08x", i, handle);
537f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            SensorInterface* sensor = mSensorMap.valueFor( handle );
538f5a1230d322c14c42331d0a1536b50c87742973bSteve Block            ALOGE_IF(!sensor, "mSensorMap[handle=0x%08x] is null!", handle);
539f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            if (sensor) {
540db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian                sensor->activate(c, false);
541f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            }
542db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        }
543db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        SensorRecord* rec = mActiveSensors.valueAt(i);
544f5a1230d322c14c42331d0a1536b50c87742973bSteve Block        ALOGE_IF(!rec, "mActiveSensors[%d] is null (handle=0x%08x)!", i, handle);
545a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block        ALOGD_IF(DEBUG_CONNECTIONS,
546a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian                "removing connection %p for sensor[%d].handle=0x%08x",
547a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian                c, i, handle);
548a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian
549db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        if (rec && rec->removeConnection(connection)) {
550a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block            ALOGD_IF(DEBUG_CONNECTIONS, "... and it was the last connection");
5517c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            mActiveSensors.removeItemsAt(i, 1);
552f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            mActiveVirtualSensors.removeItem(handle);
5537c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            delete rec;
5547c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            size--;
5557c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian        } else {
5567c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            i++;
557fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
558fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
5597c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    mActiveConnections.remove(connection);
560787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian    BatteryService::cleanup(c->getUid());
5619a844cf78f09953145200b4074d47589257a408cAravind Akella    if (c->needsWakeLock()) {
5629a844cf78f09953145200b4074d47589257a408cAravind Akella        checkWakeLockStateLocked();
5639a844cf78f09953145200b4074d47589257a408cAravind Akella    }
564fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
565fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
566700180487ffec09d9df1657b018a7caadac24b75Aravind AkellaSensor SensorService::getSensorFromHandle(int handle) const {
567700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    return mSensorMap.valueFor(handle)->getSensor();
568700180487ffec09d9df1657b018a7caadac24b75Aravind Akella}
569700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
570fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::enable(const sp<SensorEventConnection>& connection,
571724d91d778e71c8186399f4955de14b54812b3edAravind Akella        int handle, nsecs_t samplingPeriodNs,  nsecs_t maxBatchReportLatencyNs, int reservedFlags)
572fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
57350df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian    if (mInitCheck != NO_ERROR)
57450df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian        return mInitCheck;
57550df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
576f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    SensorInterface* sensor = mSensorMap.valueFor(handle);
577ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    if (sensor == NULL) {
578ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        return BAD_VALUE;
579ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    }
580700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
581700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    if (!verifyCanAccessSensor(sensor->getSensor(), "Tried enabling")) {
582700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return BAD_VALUE;
583700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
584700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
585ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    Mutex::Autolock _l(mLock);
5864342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    SensorRecord* rec = mActiveSensors.valueFor(handle);
5874342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (rec == 0) {
5884342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        rec = new SensorRecord(connection);
5894342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        mActiveSensors.add(handle, rec);
5904342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (sensor->isVirtual()) {
5914342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            mActiveVirtualSensors.add(handle, sensor);
5923560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        }
5934342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    } else {
5944342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (rec->addConnection(connection)) {
5959a844cf78f09953145200b4074d47589257a408cAravind Akella            // this sensor is already activated, but we are adding a connection that uses it.
5969a844cf78f09953145200b4074d47589257a408cAravind Akella            // Immediately send down the last known value of the requested sensor if it's not a
5974342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            // "continuous" sensor.
5980e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ON_CHANGE) {
5999a844cf78f09953145200b4074d47589257a408cAravind Akella                // NOTE: The wake_up flag of this event may get set to
6009a844cf78f09953145200b4074d47589257a408cAravind Akella                // WAKE_UP_SENSOR_EVENT_NEEDS_ACK if this is a wake_up event.
6014342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                sensors_event_t& event(mLastEventSeen.editValueFor(handle));
6024342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                if (event.version == sizeof(sensors_event_t)) {
6039a844cf78f09953145200b4074d47589257a408cAravind Akella                    if (isWakeUpSensorEvent(event) && !mWakeLockAcquired) {
6049a844cf78f09953145200b4074d47589257a408cAravind Akella                        acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
6059a844cf78f09953145200b4074d47589257a408cAravind Akella                        mWakeLockAcquired = true;
6069a844cf78f09953145200b4074d47589257a408cAravind Akella                        ALOGD_IF(DEBUG_CONNECTIONS, "acquired wakelock for on_change sensor %s",
6079a844cf78f09953145200b4074d47589257a408cAravind Akella                                                        WAKE_LOCK_NAME);
6089a844cf78f09953145200b4074d47589257a408cAravind Akella                    }
6099a844cf78f09953145200b4074d47589257a408cAravind Akella                    connection->sendEvents(&event, 1, NULL);
6109a844cf78f09953145200b4074d47589257a408cAravind Akella                    if (!connection->needsWakeLock() && mWakeLockAcquired) {
6119a844cf78f09953145200b4074d47589257a408cAravind Akella                        checkWakeLockStateLocked();
6129a844cf78f09953145200b4074d47589257a408cAravind Akella                    }
613f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                }
6147c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            }
615fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
616fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
6174342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
6184342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (connection->addSensor(handle)) {
6194342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        BatteryService::enableSensor(connection->getUid(), handle);
6204342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // the sensor was added (which means it wasn't already there)
6214342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // so, see if this connection becomes active
6224342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (mActiveConnections.indexOf(connection) < 0) {
6234342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            mActiveConnections.add(connection);
6244342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
6254342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    } else {
6264342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        ALOGW("sensor %08x already enabled in connection %p (ignoring)",
6274342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            handle, connection.get());
6284342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
6294342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
630724d91d778e71c8186399f4955de14b54812b3edAravind Akella    nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
631724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (samplingPeriodNs < minDelayNs) {
632724d91d778e71c8186399f4955de14b54812b3edAravind Akella        samplingPeriodNs = minDelayNs;
633724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
634724d91d778e71c8186399f4955de14b54812b3edAravind Akella
635724d91d778e71c8186399f4955de14b54812b3edAravind Akella    ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d rate=%lld timeout== %lld",
636724d91d778e71c8186399f4955de14b54812b3edAravind Akella             handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs);
637724d91d778e71c8186399f4955de14b54812b3edAravind Akella
638724d91d778e71c8186399f4955de14b54812b3edAravind Akella    status_t err = sensor->batch(connection.get(), handle, reservedFlags, samplingPeriodNs,
639724d91d778e71c8186399f4955de14b54812b3edAravind Akella                                 maxBatchReportLatencyNs);
6404c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    if (err == NO_ERROR) {
6414c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        connection->setFirstFlushPending(handle, true);
6424c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        status_t err_flush = sensor->flush(connection.get(), handle);
6434c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        // Flush may return error if the sensor is not activated or the underlying h/w sensor does
6444c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        // not support flush.
6454c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        if (err_flush != NO_ERROR) {
6464c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            connection->setFirstFlushPending(handle, false);
6474c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
6484c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
649724d91d778e71c8186399f4955de14b54812b3edAravind Akella
650724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (err == NO_ERROR) {
651724d91d778e71c8186399f4955de14b54812b3edAravind Akella        ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle);
652724d91d778e71c8186399f4955de14b54812b3edAravind Akella        err = sensor->activate(connection.get(), true);
653724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
654724d91d778e71c8186399f4955de14b54812b3edAravind Akella
6554342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (err != NO_ERROR) {
656724d91d778e71c8186399f4955de14b54812b3edAravind Akella        // batch/activate has failed, reset our state.
657ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        cleanupWithoutDisableLocked(connection, handle);
6584342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
659fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return err;
660fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
661fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
662fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::disable(const sp<SensorEventConnection>& connection,
663fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        int handle)
664fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
66550df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian    if (mInitCheck != NO_ERROR)
66650df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian        return mInitCheck;
66750df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
668ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    Mutex::Autolock _l(mLock);
669ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    status_t err = cleanupWithoutDisableLocked(connection, handle);
6704342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (err == NO_ERROR) {
6714342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        SensorInterface* sensor = mSensorMap.valueFor(handle);
6724342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        err = sensor ? sensor->activate(connection.get(), false) : status_t(BAD_VALUE);
6734342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
6744342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    return err;
6754342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh}
6764342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
677ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisable(
678ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        const sp<SensorEventConnection>& connection, int handle) {
679fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    Mutex::Autolock _l(mLock);
680ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    return cleanupWithoutDisableLocked(connection, handle);
681ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian}
682ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian
683ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisableLocked(
684ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        const sp<SensorEventConnection>& connection, int handle) {
685fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    SensorRecord* rec = mActiveSensors.valueFor(handle);
686fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (rec) {
687fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        // see if this connection becomes inactive
688787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian        if (connection->removeSensor(handle)) {
689787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian            BatteryService::disableSensor(connection->getUid(), handle);
690787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian        }
691fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        if (connection->hasAnySensor() == false) {
692fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            mActiveConnections.remove(connection);
693fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
694fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        // see if this sensor becomes inactive
695fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        if (rec->removeConnection(connection)) {
696fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            mActiveSensors.removeItem(handle);
697f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            mActiveVirtualSensors.removeItem(handle);
698fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            delete rec;
699fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
7004342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        return NO_ERROR;
7017c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    }
7024342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    return BAD_VALUE;
703fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
704fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
7057c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianstatus_t SensorService::setEventRate(const sp<SensorEventConnection>& connection,
706fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        int handle, nsecs_t ns)
707fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
70850df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian    if (mInitCheck != NO_ERROR)
70950df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian        return mInitCheck;
71050df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
711ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian    SensorInterface* sensor = mSensorMap.valueFor(handle);
712ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian    if (!sensor)
713ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian        return BAD_VALUE;
714ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian
715700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    if (!verifyCanAccessSensor(sensor->getSensor(), "Tried configuring")) {
716700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return BAD_VALUE;
717700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
718700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
7191cd700015318727d6d42236ab6274f1949fb08baMathias Agopian    if (ns < 0)
7201cd700015318727d6d42236ab6274f1949fb08baMathias Agopian        return BAD_VALUE;
7211cd700015318727d6d42236ab6274f1949fb08baMathias Agopian
72262569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian    nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
72362569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian    if (ns < minDelayNs) {
72462569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian        ns = minDelayNs;
725ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian    }
726ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian
727f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    return sensor->setDelay(connection.get(), handle, ns);
728fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
729fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
730724d91d778e71c8186399f4955de14b54812b3edAravind Akellastatus_t SensorService::flushSensor(const sp<SensorEventConnection>& connection,
731724d91d778e71c8186399f4955de14b54812b3edAravind Akella                                    int handle) {
732700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    if (mInitCheck != NO_ERROR) return mInitCheck;
733700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    SensorInterface* sensor = mSensorMap.valueFor(handle);
734700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    if (sensor == NULL) {
735700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return BAD_VALUE;
736700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
737700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
738700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    if (!verifyCanAccessSensor(sensor->getSensor(), "Tried flushing")) {
739700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return BAD_VALUE;
740700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
741700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
7420e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella    if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
7430e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella        ALOGE("flush called on a one-shot sensor");
744700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return INVALID_OPERATION;
745700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
746700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    return sensor->flush(connection.get(), handle);
747700180487ffec09d9df1657b018a7caadac24b75Aravind Akella}
748700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
749700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
750700180487ffec09d9df1657b018a7caadac24b75Aravind Akellabool SensorService::canAccessSensor(const Sensor& sensor) {
751700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    String16 permissionString(sensor.getRequiredPermission());
752700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    return permissionString.size() == 0 ||
753700180487ffec09d9df1657b018a7caadac24b75Aravind Akella            PermissionCache::checkCallingPermission(permissionString);
754724d91d778e71c8186399f4955de14b54812b3edAravind Akella}
755700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
756700180487ffec09d9df1657b018a7caadac24b75Aravind Akellabool SensorService::verifyCanAccessSensor(const Sensor& sensor, const char* operation) {
757700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    if (canAccessSensor(sensor)) {
758700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return true;
759700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    } else {
760700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        String8 errorMessage;
761700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        errorMessage.appendFormat(
762700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                "%s a sensor (%s) without holding its required permission: %s",
763700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                operation,
764700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                sensor.getName().string(),
765700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                sensor.getRequiredPermission().string());
766700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return false;
767700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
768700180487ffec09d9df1657b018a7caadac24b75Aravind Akella}
769700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
7709a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockState() {
7719a844cf78f09953145200b4074d47589257a408cAravind Akella    Mutex::Autolock _l(mLock);
7729a844cf78f09953145200b4074d47589257a408cAravind Akella    checkWakeLockStateLocked();
7739a844cf78f09953145200b4074d47589257a408cAravind Akella}
7749a844cf78f09953145200b4074d47589257a408cAravind Akella
7759a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockStateLocked() {
7769a844cf78f09953145200b4074d47589257a408cAravind Akella    if (!mWakeLockAcquired) {
7779a844cf78f09953145200b4074d47589257a408cAravind Akella        return;
7789a844cf78f09953145200b4074d47589257a408cAravind Akella    }
7799a844cf78f09953145200b4074d47589257a408cAravind Akella    bool releaseLock = true;
7809a844cf78f09953145200b4074d47589257a408cAravind Akella    for (size_t i=0 ; i<mActiveConnections.size() ; i++) {
7819a844cf78f09953145200b4074d47589257a408cAravind Akella        sp<SensorEventConnection> connection(mActiveConnections[i].promote());
7829a844cf78f09953145200b4074d47589257a408cAravind Akella        if (connection != 0) {
7839a844cf78f09953145200b4074d47589257a408cAravind Akella            if (connection->needsWakeLock()) {
7849a844cf78f09953145200b4074d47589257a408cAravind Akella                releaseLock = false;
7859a844cf78f09953145200b4074d47589257a408cAravind Akella                break;
7869a844cf78f09953145200b4074d47589257a408cAravind Akella            }
7879a844cf78f09953145200b4074d47589257a408cAravind Akella        }
7889a844cf78f09953145200b4074d47589257a408cAravind Akella    }
7899a844cf78f09953145200b4074d47589257a408cAravind Akella    if (releaseLock) {
7909a844cf78f09953145200b4074d47589257a408cAravind Akella        ALOGD_IF(DEBUG_CONNECTIONS, "releasing wakelock %s", WAKE_LOCK_NAME);
7919a844cf78f09953145200b4074d47589257a408cAravind Akella        release_wake_lock(WAKE_LOCK_NAME);
7929a844cf78f09953145200b4074d47589257a408cAravind Akella        mWakeLockAcquired = false;
7939a844cf78f09953145200b4074d47589257a408cAravind Akella    }
7949a844cf78f09953145200b4074d47589257a408cAravind Akella}
795fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// ---------------------------------------------------------------------------
796fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
797fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorRecord::SensorRecord(
798fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        const sp<SensorEventConnection>& connection)
799fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
800fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    mConnections.add(connection);
801fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
802fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
8037c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianbool SensorService::SensorRecord::addConnection(
804fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        const sp<SensorEventConnection>& connection)
805fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
806fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (mConnections.indexOf(connection) < 0) {
807fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        mConnections.add(connection);
8087c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian        return true;
809fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
8107c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    return false;
811fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
812fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
813fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::SensorRecord::removeConnection(
814fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        const wp<SensorEventConnection>& connection)
815fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
816fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    ssize_t index = mConnections.indexOf(connection);
817fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (index >= 0) {
818fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        mConnections.removeItemsAt(index, 1);
819fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
820fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return mConnections.size() ? false : true;
821fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
822fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
823fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// ---------------------------------------------------------------------------
824fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
825fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorEventConnection::SensorEventConnection(
8265307d17fe33fc26eeeacd6339a9fbfe96cf56873Mathias Agopian        const sp<SensorService>& service, uid_t uid)
8279a844cf78f09953145200b4074d47589257a408cAravind Akella    : mService(service), mUid(uid), mWakeLockRefCount(0)
828fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
8294c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    const SensorDevice& device(SensorDevice::getInstance());
8304c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    if (device.getHalDeviceVersion() >= SENSORS_DEVICE_API_VERSION_1_1) {
8314c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        // Increase socket buffer size to 1MB for batching capabilities.
8324c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        mChannel = new BitTube(service->mSocketBufferSize);
8334c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    } else {
8344c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        mChannel = new BitTube(SOCKET_BUFFER_SIZE_NON_BATCHED);
8354c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
836fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
837fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
838fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorEventConnection::~SensorEventConnection()
839fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
840a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block    ALOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this);
841fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    mService->cleanupConnection(this);
842fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
843fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
844fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianvoid SensorService::SensorEventConnection::onFirstRef()
845fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
846fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
847fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
8489a844cf78f09953145200b4074d47589257a408cAravind Akellabool SensorService::SensorEventConnection::needsWakeLock() {
8499a844cf78f09953145200b4074d47589257a408cAravind Akella    Mutex::Autolock _l(mConnectionLock);
8509a844cf78f09953145200b4074d47589257a408cAravind Akella    return mWakeLockRefCount > 0;
8519a844cf78f09953145200b4074d47589257a408cAravind Akella}
8529a844cf78f09953145200b4074d47589257a408cAravind Akella
8534c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akellavoid SensorService::SensorEventConnection::dump(String8& result) {
8544c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    Mutex::Autolock _l(mConnectionLock);
8559a844cf78f09953145200b4074d47589257a408cAravind Akella    result.appendFormat("%d WakeLockRefCount\n", mWakeLockRefCount);
8564c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
8574c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        const FlushInfo& flushInfo = mSensorInfo.valueAt(i);
858eefced119bc568d773b86c34cd8bc9d9574638f6Patrick Tjin        result.appendFormat("\t %s | status: %s | pending flush events %d | uid %d\n",
8594c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                            mService->getSensorName(mSensorInfo.keyAt(i)).string(),
8604c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                            flushInfo.mFirstFlushPending ? "First flush pending" :
8614c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                                                           "active",
862eefced119bc568d773b86c34cd8bc9d9574638f6Patrick Tjin                            flushInfo.mPendingFlushEventsToSend,
863eefced119bc568d773b86c34cd8bc9d9574638f6Patrick Tjin                            mUid);
8644c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
8654c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella}
8664c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
8677c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianbool SensorService::SensorEventConnection::addSensor(int32_t handle) {
86871d7a5c289c6ef6b5fc86dd4784a075ca6470e38Mathias Agopian    Mutex::Autolock _l(mConnectionLock);
869700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    if (!verifyCanAccessSensor(mService->getSensorFromHandle(handle), "Tried adding")) {
870700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return false;
871700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
8724c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    if (mSensorInfo.indexOfKey(handle) < 0) {
8734c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        mSensorInfo.add(handle, FlushInfo());
8747c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian        return true;
875fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
8767c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    return false;
877fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
878fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
8797c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianbool SensorService::SensorEventConnection::removeSensor(int32_t handle) {
88071d7a5c289c6ef6b5fc86dd4784a075ca6470e38Mathias Agopian    Mutex::Autolock _l(mConnectionLock);
8814c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    if (mSensorInfo.removeItem(handle) >= 0) {
8827c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian        return true;
8837c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    }
8847c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    return false;
885fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
886fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
887fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
88871d7a5c289c6ef6b5fc86dd4784a075ca6470e38Mathias Agopian    Mutex::Autolock _l(mConnectionLock);
8894c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    return mSensorInfo.indexOfKey(handle) >= 0;
890fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
891fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
892fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::SensorEventConnection::hasAnySensor() const {
89371d7a5c289c6ef6b5fc86dd4784a075ca6470e38Mathias Agopian    Mutex::Autolock _l(mConnectionLock);
8947c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    return mSensorInfo.size() ? true : false;
8957c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian}
8967c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian
8974c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akellavoid SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle,
8984c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                                bool value) {
8994c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    Mutex::Autolock _l(mConnectionLock);
9004c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    ssize_t index = mSensorInfo.indexOfKey(handle);
9014c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    if (index >= 0) {
9024c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
9034c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        flushInfo.mFirstFlushPending = value;
9044c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
9054c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella}
9064c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
907fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::SensorEventConnection::sendEvents(
908cf51001dbf28e9885fcacd4048902f1c75768fe9Mathias Agopian        sensors_event_t const* buffer, size_t numEvents,
909cf51001dbf28e9885fcacd4048902f1c75768fe9Mathias Agopian        sensors_event_t* scratch)
910fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
911cf51001dbf28e9885fcacd4048902f1c75768fe9Mathias Agopian    // filter out events not for this connection
9123560fb24b668675627934356f210d84d19bf4e56Mathias Agopian    size_t count = 0;
9139a844cf78f09953145200b4074d47589257a408cAravind Akella    Mutex::Autolock _l(mConnectionLock);
9143560fb24b668675627934356f210d84d19bf4e56Mathias Agopian    if (scratch) {
9153560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        size_t i=0;
9163560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        while (i<numEvents) {
917724d91d778e71c8186399f4955de14b54812b3edAravind Akella            int32_t curr = buffer[i].sensor;
918724d91d778e71c8186399f4955de14b54812b3edAravind Akella            if (buffer[i].type == SENSOR_TYPE_META_DATA) {
919724d91d778e71c8186399f4955de14b54812b3edAravind Akella                ALOGD_IF(DEBUG_CONNECTIONS, "flush complete event sensor==%d ",
920724d91d778e71c8186399f4955de14b54812b3edAravind Akella                         buffer[i].meta_data.sensor);
921724d91d778e71c8186399f4955de14b54812b3edAravind Akella                // Setting curr to the correct sensor to ensure the sensor events per connection are
922724d91d778e71c8186399f4955de14b54812b3edAravind Akella                // filtered correctly. buffer[i].sensor is zero for meta_data events.
923724d91d778e71c8186399f4955de14b54812b3edAravind Akella                curr = buffer[i].meta_data.sensor;
924724d91d778e71c8186399f4955de14b54812b3edAravind Akella            }
9254c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            ssize_t index = mSensorInfo.indexOfKey(curr);
9264c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            if (index >= 0 && mSensorInfo[index].mFirstFlushPending == true &&
9274c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                buffer[i].type == SENSOR_TYPE_META_DATA) {
9284c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                // This is the first flush before activate is called. Events can now be sent for
9294c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                // this sensor on this connection.
9304c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                ALOGD_IF(DEBUG_CONNECTIONS, "First flush event for sensor==%d ",
9314c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                         buffer[i].meta_data.sensor);
9324c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                mSensorInfo.editValueAt(index).mFirstFlushPending = false;
9334c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
9344c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            if (index >= 0 && mSensorInfo[index].mFirstFlushPending == false)  {
9353560fb24b668675627934356f210d84d19bf4e56Mathias Agopian                do {
9364c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                    scratch[count++] = buffer[i++];
937724d91d778e71c8186399f4955de14b54812b3edAravind Akella                } while ((i<numEvents) && ((buffer[i].sensor == curr) ||
938724d91d778e71c8186399f4955de14b54812b3edAravind Akella                         (buffer[i].type == SENSOR_TYPE_META_DATA  &&
939724d91d778e71c8186399f4955de14b54812b3edAravind Akella                          buffer[i].meta_data.sensor == curr)));
9403560fb24b668675627934356f210d84d19bf4e56Mathias Agopian            } else {
9413560fb24b668675627934356f210d84d19bf4e56Mathias Agopian                i++;
9423560fb24b668675627934356f210d84d19bf4e56Mathias Agopian            }
943cf51001dbf28e9885fcacd4048902f1c75768fe9Mathias Agopian        }
9443560fb24b668675627934356f210d84d19bf4e56Mathias Agopian    } else {
9453560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        scratch = const_cast<sensors_event_t *>(buffer);
9463560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        count = numEvents;
947cf51001dbf28e9885fcacd4048902f1c75768fe9Mathias Agopian    }
948fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
9494c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    // Send pending flush events (if any) before sending events from the cache.
9504c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    {
9514c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        ASensorEvent flushCompleteEvent;
9524c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        flushCompleteEvent.type = SENSOR_TYPE_META_DATA;
9534c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        flushCompleteEvent.sensor = 0;
9544c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        // Loop through all the sensors for this connection and check if there are any pending
9554c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        // flush complete events to be sent.
9564c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        for (size_t i = 0; i < mSensorInfo.size(); ++i) {
9574c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            FlushInfo& flushInfo = mSensorInfo.editValueAt(i);
9584c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            while (flushInfo.mPendingFlushEventsToSend > 0) {
9594c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                flushCompleteEvent.meta_data.sensor = mSensorInfo.keyAt(i);
9604c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                ssize_t size = SensorEventQueue::write(mChannel, &flushCompleteEvent, 1);
9614c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                if (size < 0) {
9624c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                    // ALOGW("dropping %d events on the floor", count);
963c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella                    countFlushCompleteEventsLocked(scratch, count);
9644c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                    return size;
9654c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                }
9664c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                ALOGD_IF(DEBUG_CONNECTIONS, "sent dropped flush complete event==%d ",
9674c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                         flushCompleteEvent.meta_data.sensor);
9684c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                flushInfo.mPendingFlushEventsToSend--;
9694c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
9704c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
9714c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
9724c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
973b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella    // Early return if there are no events for this connection.
974b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella    if (count == 0) {
975b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella        return status_t(NO_ERROR);
976b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella    }
977b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella
9789a844cf78f09953145200b4074d47589257a408cAravind Akella    int numWakeUpSensorEvents = countWakeUpSensorEventsLocked(scratch, count);
979907103bf186cfdd2ed9eb3b6c36de53ade7b16f6Mathias Agopian    // NOTE: ASensorEvent and sensors_event_t are the same type
980907103bf186cfdd2ed9eb3b6c36de53ade7b16f6Mathias Agopian    ssize_t size = SensorEventQueue::write(mChannel,
981907103bf186cfdd2ed9eb3b6c36de53ade7b16f6Mathias Agopian            reinterpret_cast<ASensorEvent const*>(scratch), count);
982fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (size == -EAGAIN) {
983fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        // the destination doesn't accept events anymore, it's probably
984fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        // full. For now, we just drop the events on the floor.
9854c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        // ALOGW("dropping %d events on the floor", count);
986c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella        countFlushCompleteEventsLocked(scratch, count);
9879a844cf78f09953145200b4074d47589257a408cAravind Akella        mWakeLockRefCount -= numWakeUpSensorEvents;
988fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        return size;
989fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
9901e0b1e8491e5f6dc59faabe70cbfa942853150e0Jeff Brown    return size < 0 ? status_t(size) : status_t(NO_ERROR);
991fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
992fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
993c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akellavoid SensorService::SensorEventConnection::countFlushCompleteEventsLocked(
9944c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                sensors_event_t* scratch, const int numEventsDropped) {
9954c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    ALOGD_IF(DEBUG_CONNECTIONS, "dropping %d events ", numEventsDropped);
9964c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    // Count flushComplete events in the events that are about to the dropped. These will be sent
9974c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    // separately before the next batch of events.
9984c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    for (int j = 0; j < numEventsDropped; ++j) {
9994c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        if (scratch[j].type == SENSOR_TYPE_META_DATA) {
10004c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            FlushInfo& flushInfo = mSensorInfo.editValueFor(scratch[j].meta_data.sensor);
10014c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            flushInfo.mPendingFlushEventsToSend++;
10024c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            ALOGD_IF(DEBUG_CONNECTIONS, "increment pendingFlushCount %d",
10034c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                     flushInfo.mPendingFlushEventsToSend);
10044c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
10054c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
10064c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    return;
10074c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella}
10084c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
10099a844cf78f09953145200b4074d47589257a408cAravind Akellaint SensorService::SensorEventConnection::countWakeUpSensorEventsLocked(
10109a844cf78f09953145200b4074d47589257a408cAravind Akella                       sensors_event_t* scratch, const int count) {
10119a844cf78f09953145200b4074d47589257a408cAravind Akella    for (int i = 0; i < count; ++i) {
10129a844cf78f09953145200b4074d47589257a408cAravind Akella        if (mService->isWakeUpSensorEvent(scratch[i])) {
10139a844cf78f09953145200b4074d47589257a408cAravind Akella            scratch[i].flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
10149a844cf78f09953145200b4074d47589257a408cAravind Akella            ++mWakeLockRefCount;
10159a844cf78f09953145200b4074d47589257a408cAravind Akella            return 1;
10169a844cf78f09953145200b4074d47589257a408cAravind Akella        }
10179a844cf78f09953145200b4074d47589257a408cAravind Akella    }
10189a844cf78f09953145200b4074d47589257a408cAravind Akella    return 0;
10199a844cf78f09953145200b4074d47589257a408cAravind Akella}
10209a844cf78f09953145200b4074d47589257a408cAravind Akella
1021b3989276d17f2b083bec67b695d1078fb86c6c53Mathias Agopiansp<BitTube> SensorService::SensorEventConnection::getSensorChannel() const
1022fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
1023fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return mChannel;
1024fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1025fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1026fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::SensorEventConnection::enableDisable(
1027724d91d778e71c8186399f4955de14b54812b3edAravind Akella        int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
1028724d91d778e71c8186399f4955de14b54812b3edAravind Akella        int reservedFlags)
1029fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
1030fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    status_t err;
1031fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (enabled) {
1032724d91d778e71c8186399f4955de14b54812b3edAravind Akella        err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
1033724d91d778e71c8186399f4955de14b54812b3edAravind Akella                               reservedFlags);
1034fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    } else {
1035fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        err = mService->disable(this, handle);
1036fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
1037fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return err;
1038fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1039fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1040fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::SensorEventConnection::setEventRate(
1041724d91d778e71c8186399f4955de14b54812b3edAravind Akella        int handle, nsecs_t samplingPeriodNs)
1042fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
1043724d91d778e71c8186399f4955de14b54812b3edAravind Akella    return mService->setEventRate(this, handle, samplingPeriodNs);
1044fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1045fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1046701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akellastatus_t  SensorService::SensorEventConnection::flush() {
1047c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella    SensorDevice& dev(SensorDevice::getInstance());
1048c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella    const int halVersion = dev.getHalDeviceVersion();
1049701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella    Mutex::Autolock _l(mConnectionLock);
1050701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella    status_t err(NO_ERROR);
1051c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella    // Loop through all sensors for this connection and call flush on each of them.
1052701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
1053701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella        const int handle = mSensorInfo.keyAt(i);
1054b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella        if (halVersion < SENSORS_DEVICE_API_VERSION_1_1 || mService->isVirtualSensor(handle)) {
1055c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella            // For older devices just increment pending flush count which will send a trivial
1056c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella            // flush complete event.
1057c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella            FlushInfo& flushInfo = mSensorInfo.editValueFor(handle);
1058c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella            flushInfo.mPendingFlushEventsToSend++;
1059c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella        } else {
1060c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella            status_t err_flush = mService->flushSensor(this, handle);
1061c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella            if (err_flush != NO_ERROR) {
1062c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella                ALOGE("Flush error handle=%d %s", handle, strerror(-err_flush));
1063c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella            }
1064c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella            err = (err_flush != NO_ERROR) ? err_flush : err;
1065701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella        }
1066701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella    }
1067701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella    return err;
1068724d91d778e71c8186399f4955de14b54812b3edAravind Akella}
10694c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
10709a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::SensorEventConnection::decreaseWakeLockRefCount() {
10719a844cf78f09953145200b4074d47589257a408cAravind Akella    {
10729a844cf78f09953145200b4074d47589257a408cAravind Akella        Mutex::Autolock _l(mConnectionLock);
10739a844cf78f09953145200b4074d47589257a408cAravind Akella        --mWakeLockRefCount;
10749a844cf78f09953145200b4074d47589257a408cAravind Akella    }
10759a844cf78f09953145200b4074d47589257a408cAravind Akella    // Release the lock before calling checkWakeLockState which also needs the same connectionLock.
10769a844cf78f09953145200b4074d47589257a408cAravind Akella    if (mWakeLockRefCount == 0) {
10779a844cf78f09953145200b4074d47589257a408cAravind Akella        mService->checkWakeLockState();
10789a844cf78f09953145200b4074d47589257a408cAravind Akella    }
10799a844cf78f09953145200b4074d47589257a408cAravind Akella}
10809a844cf78f09953145200b4074d47589257a408cAravind Akella
1081fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// ---------------------------------------------------------------------------
1082fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}; // namespace android
1083fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1084