SensorService.cpp revision 2576cb63b3fe1592f54816625036566b9eb0793a
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
173301542828febc768e1df42892cfac4992c35474Mathias Agopian#include <cutils/properties.h>
183301542828febc768e1df42892cfac4992c35474Mathias Agopian
19b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav#include <binder/AppOpsManager.h>
20fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <binder/BinderService.h>
21451beee076cac09f817abae78a990dea108a9482Mathias Agopian#include <binder/IServiceManager.h>
221cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian#include <binder/PermissionCache.h>
23fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
24907103bf186cfdd2ed9eb3b6c36de53ade7b16f6Mathias Agopian#include <gui/SensorEventQueue.h>
25fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
26fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <hardware/sensors.h>
274342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh#include <hardware_legacy/power.h>
28fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
29787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian#include "BatteryService.h"
30984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "CorrectedGyroSensor.h"
31f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "GravitySensor.h"
32f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "LinearAccelerationSensor.h"
33984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "OrientationSensor.h"
34f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "RotationVectorSensor.h"
35984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "SensorFusion.h"
36eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu
37984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "SensorService.h"
38eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include "SensorEventConnection.h"
39eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include "SensorEventAckReceiver.h"
40eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include "SensorRecord.h"
41eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include "SensorRegistrationInfo.h"
42eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include "MostRecentEventLogger.h"
43eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu
44eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <inttypes.h>
45eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <math.h>
46eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <stdint.h>
47eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <sys/types.h>
48eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <sys/socket.h>
49fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
50fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopiannamespace android {
51fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// ---------------------------------------------------------------------------
52fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
533301542828febc768e1df42892cfac4992c35474Mathias Agopian/*
543301542828febc768e1df42892cfac4992c35474Mathias Agopian * Notes:
553301542828febc768e1df42892cfac4992c35474Mathias Agopian *
563301542828febc768e1df42892cfac4992c35474Mathias Agopian * - what about a gyro-corrected magnetic-field sensor?
573301542828febc768e1df42892cfac4992c35474Mathias Agopian * - run mag sensor from time to time to force calibration
583301542828febc768e1df42892cfac4992c35474Mathias Agopian * - gravity sensor length is wrong (=> drift in linear-acc sensor)
593301542828febc768e1df42892cfac4992c35474Mathias Agopian *
603301542828febc768e1df42892cfac4992c35474Mathias Agopian */
613301542828febc768e1df42892cfac4992c35474Mathias Agopian
628ef3c89eb2030395f8a342bd16dbb344957ab275Aravind Akellaconst char* SensorService::WAKE_LOCK_NAME = "SensorService_wakelock";
63a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella// Permissions.
64a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatic const String16 sDump("android.permission.DUMP");
654342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
66fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorService()
678a96955c8e14db40b16164236830fc9506a00872Aravind Akella    : mInitCheck(NO_INIT), mSocketBufferSize(SOCKET_BUFFER_SIZE_NON_BATCHED),
688a96955c8e14db40b16164236830fc9506a00872Aravind Akella      mWakeLockAcquired(false)
69fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
70fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
71fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
72fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianvoid SensorService::onFirstRef()
73fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
74a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block    ALOGD("nuSensorService starting...");
75f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    SensorDevice& dev(SensorDevice::getInstance());
76fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
77f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    if (dev.initCheck() == NO_ERROR) {
78f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        sensor_t const* list;
797b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian        ssize_t count = dev.getSensorList(&list);
807b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian        if (count > 0) {
817b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            ssize_t orientationIndex = -1;
82f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella            bool hasGyro = false, hasAccel = false, hasMag = false;
837b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            uint32_t virtualSensorsNeeds =
847b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    (1<<SENSOR_TYPE_GRAVITY) |
857b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    (1<<SENSOR_TYPE_LINEAR_ACCELERATION) |
86f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                    (1<<SENSOR_TYPE_ROTATION_VECTOR) |
87f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                    (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR) |
88f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                    (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR);
897b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian
907b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            mLastEventSeen.setCapacity(count);
917b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            for (ssize_t i=0 ; i<count ; i++) {
92f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                bool useThisSensor=true;
93f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu
947b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                switch (list[i].type) {
95f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella                    case SENSOR_TYPE_ACCELEROMETER:
96f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella                        hasAccel = true;
97f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella                        break;
98f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella                    case SENSOR_TYPE_MAGNETIC_FIELD:
99f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella                        hasMag = true;
100f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella                        break;
1017b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_ORIENTATION:
1027b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        orientationIndex = i;
1037b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        break;
1047b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_GYROSCOPE:
1050319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
1067b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        hasGyro = true;
1077b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        break;
1087b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_GRAVITY:
1097b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_LINEAR_ACCELERATION:
1107b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_ROTATION_VECTOR:
111f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                    case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
112f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                    case SENSOR_TYPE_GAME_ROTATION_VECTOR:
113f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                        if (IGNORE_HARDWARE_FUSION) {
114f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                            useThisSensor = false;
115f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                        } else {
116f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                            virtualSensorsNeeds &= ~(1<<list[i].type);
117f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                        }
1187b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        break;
1197b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                }
120f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                if (useThisSensor) {
121f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                    registerSensor( new HardwareSensor(list[i]) );
122f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                }
12350df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian            }
124fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1257b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            // it's safe to instantiate the SensorFusion object here
1267b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            // (it wants to be instantiated after h/w sensors have been
1277b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            // registered)
128d4036b6b7f9609fe09efabdbfbb8c8f9428f76f7Andreas Gampe            SensorFusion::getInstance();
1297b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian
1300319306670b0344da99efa606b6f172dde575a39Mathias Agopian            // build the sensor list returned to users
1310319306670b0344da99efa606b6f172dde575a39Mathias Agopian            mUserSensorList = mSensorList;
1320319306670b0344da99efa606b6f172dde575a39Mathias Agopian
133f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella            if (hasGyro && hasAccel && hasMag) {
1340319306670b0344da99efa606b6f172dde575a39Mathias Agopian                // Add Android virtual sensors if they're not already
1350319306670b0344da99efa606b6f172dde575a39Mathias Agopian                // available in the HAL
136f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                Sensor aSensor;
1377b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian
1380319306670b0344da99efa606b6f172dde575a39Mathias Agopian                aSensor = registerVirtualSensor( new RotationVectorSensor() );
1390319306670b0344da99efa606b6f172dde575a39Mathias Agopian                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
1400319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    mUserSensorList.add(aSensor);
1410319306670b0344da99efa606b6f172dde575a39Mathias Agopian                }
142f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
1430319306670b0344da99efa606b6f172dde575a39Mathias Agopian                aSensor = registerVirtualSensor( new OrientationSensor() );
1440319306670b0344da99efa606b6f172dde575a39Mathias Agopian                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
1450319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    // if we are doing our own rotation-vector, also add
1460319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    // the orientation sensor and remove the HAL provided one.
1470319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    mUserSensorList.replaceAt(aSensor, orientationIndex);
1487b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                }
1490319306670b0344da99efa606b6f172dde575a39Mathias Agopian
150f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                aSensor = registerVirtualSensor(
151f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                                new LinearAccelerationSensor(list, count) );
152f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                if (virtualSensorsNeeds &
153f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                            (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) {
154f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                    mUserSensorList.add(aSensor);
155f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                }
156f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu
1570319306670b0344da99efa606b6f172dde575a39Mathias Agopian                // virtual debugging sensors are not added to mUserSensorList
1580319306670b0344da99efa606b6f172dde575a39Mathias Agopian                registerVirtualSensor( new CorrectedGyroSensor(list, count) );
1590319306670b0344da99efa606b6f172dde575a39Mathias Agopian                registerVirtualSensor( new GyroDriftSensor() );
160010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian            }
161010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian
162f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu            if (hasAccel && hasGyro) {
163f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                Sensor aSensor;
164f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu
165f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                aSensor = registerVirtualSensor(
166f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                                new GravitySensor(list, count) );
167f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) {
168f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                    mUserSensorList.add(aSensor);
169f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                }
170f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu
171f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                aSensor = registerVirtualSensor(
172f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                                new GameRotationVectorSensor() );
173f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                if (virtualSensorsNeeds &
174f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                            (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR)) {
175f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                    mUserSensorList.add(aSensor);
176f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                }
177f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu            }
178f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu
179f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu            if (hasAccel && hasMag) {
180f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                Sensor aSensor;
181f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu
182f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                aSensor = registerVirtualSensor(
183f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                                new GeoMagRotationVectorSensor() );
184f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                if (virtualSensorsNeeds &
185f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                        (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR)) {
186f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                    mUserSensorList.add(aSensor);
187f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                }
188f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu            }
189f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu
19033264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian            // debugging sensor list
1910319306670b0344da99efa606b6f172dde575a39Mathias Agopian            mUserSensorListDebug = mSensorList;
19233264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian
1935466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            // Check if the device really supports batching by looking at the FIFO event
1945466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            // counts for each sensor.
1955466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            bool batchingSupported = false;
196b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            for (size_t i = 0; i < mSensorList.size(); ++i) {
1975466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                if (mSensorList[i].getFifoMaxEventCount() > 0) {
1985466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                    batchingSupported = true;
1995466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                    break;
2005466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                }
2015466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            }
2025466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella
2035466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            if (batchingSupported) {
2045466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                // Increase socket buffer size to a max of 100 KB for batching capabilities.
2055466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                mSocketBufferSize = MAX_SOCKET_BUFFER_SIZE_BATCHED;
2065466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            } else {
2075466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                mSocketBufferSize = SOCKET_BUFFER_SIZE_NON_BATCHED;
2085466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            }
2095466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella
2105466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            // Compare the socketBufferSize value against the system limits and limit
2115466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            // it to maxSystemSocketBufferSize if necessary.
2124c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            FILE *fp = fopen("/proc/sys/net/core/wmem_max", "r");
2134c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            char line[128];
2144c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            if (fp != NULL && fgets(line, sizeof(line), fp) != NULL) {
2154c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                line[sizeof(line) - 1] = '\0';
2165466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                size_t maxSystemSocketBufferSize;
2175466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                sscanf(line, "%zu", &maxSystemSocketBufferSize);
2185466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                if (mSocketBufferSize > maxSystemSocketBufferSize) {
2195466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                    mSocketBufferSize = maxSystemSocketBufferSize;
2204c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                }
2214c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
2224c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            if (fp) {
2234c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                fclose(fp);
2244c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
2254c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
2269a844cf78f09953145200b4074d47589257a408cAravind Akella            mWakeLockAcquired = false;
22756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            mLooper = new Looper(false);
2288493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
2298493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            mSensorEventBuffer = new sensors_event_t[minBufferSize];
2308493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            mSensorEventScratch = new sensors_event_t[minBufferSize];
2318493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize];
232a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella            mCurrentOperatingMode = NORMAL;
2337830ef3dd0ff3749d974c2dd85a8fa59dc47aecaAravind Akella
23418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            mNextSensorRegIndex = 0;
23518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            for (int i = 0; i < SENSOR_REGISTRATIONS_BUF_SIZE; ++i) {
23618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                mLastNSensorRegistrations.push();
23718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            }
23818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella
23918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            mInitCheck = NO_ERROR;
240b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            mAckReceiver = new SensorEventAckReceiver(this);
241b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
2427830ef3dd0ff3749d974c2dd85a8fa59dc47aecaAravind Akella            run("SensorService", PRIORITY_URGENT_DISPLAY);
2437b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian        }
244fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
245fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
246fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
2470319306670b0344da99efa606b6f172dde575a39Mathias AgopianSensor SensorService::registerSensor(SensorInterface* s)
248f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{
249f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    const Sensor sensor(s->getSensor());
250f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    // add to the sensor list (returned to clients)
251f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    mSensorList.add(sensor);
252f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    // add to our handle->SensorInterface mapping
253f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    mSensorMap.add(sensor.getHandle(), s);
254f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    // create an entry in the mLastEventSeen array
255444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    mLastEventSeen.add(sensor.getHandle(), NULL);
2560319306670b0344da99efa606b6f172dde575a39Mathias Agopian
2570319306670b0344da99efa606b6f172dde575a39Mathias Agopian    return sensor;
258f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
259f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
2602576cb63b3fe1592f54816625036566b9eb0793aPeng XuSensor SensorService::registerDynamicSensor(SensorInterface* s)
2612576cb63b3fe1592f54816625036566b9eb0793aPeng Xu{
2622576cb63b3fe1592f54816625036566b9eb0793aPeng Xu    Sensor sensor = registerSensor(s);
2632576cb63b3fe1592f54816625036566b9eb0793aPeng Xu    mDynamicSensorList.add(sensor);
2642576cb63b3fe1592f54816625036566b9eb0793aPeng Xu    return sensor;
2652576cb63b3fe1592f54816625036566b9eb0793aPeng Xu}
2662576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
2672576cb63b3fe1592f54816625036566b9eb0793aPeng Xubool SensorService::unregisterDynamicSensor(int handle) {
2682576cb63b3fe1592f54816625036566b9eb0793aPeng Xu    bool found = false;
2692576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
2702576cb63b3fe1592f54816625036566b9eb0793aPeng Xu    for (size_t i=0 ; i<mSensorList.size() ; i++) {
2712576cb63b3fe1592f54816625036566b9eb0793aPeng Xu        if (mSensorList[i].getHandle() == handle) {
2722576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            mSensorList.removeAt(i);
2732576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            found = true;
2742576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            break;
2752576cb63b3fe1592f54816625036566b9eb0793aPeng Xu        }
2762576cb63b3fe1592f54816625036566b9eb0793aPeng Xu    }
2772576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
2782576cb63b3fe1592f54816625036566b9eb0793aPeng Xu    if (found) {
2792576cb63b3fe1592f54816625036566b9eb0793aPeng Xu        for (size_t i=0 ; i<mDynamicSensorList.size() ; i++) {
2802576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            if (mDynamicSensorList[i].getHandle() == handle) {
2812576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                mDynamicSensorList.removeAt(i);
2822576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            }
2832576cb63b3fe1592f54816625036566b9eb0793aPeng Xu        }
2842576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
2852576cb63b3fe1592f54816625036566b9eb0793aPeng Xu        mSensorMap.removeItem(handle);
2862576cb63b3fe1592f54816625036566b9eb0793aPeng Xu        mLastEventSeen.removeItem(handle);
2872576cb63b3fe1592f54816625036566b9eb0793aPeng Xu    }
2882576cb63b3fe1592f54816625036566b9eb0793aPeng Xu    return found;
2892576cb63b3fe1592f54816625036566b9eb0793aPeng Xu}
2902576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
2910319306670b0344da99efa606b6f172dde575a39Mathias AgopianSensor SensorService::registerVirtualSensor(SensorInterface* s)
292f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{
2930319306670b0344da99efa606b6f172dde575a39Mathias Agopian    Sensor sensor = registerSensor(s);
294f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    mVirtualSensorList.add( s );
2950319306670b0344da99efa606b6f172dde575a39Mathias Agopian    return sensor;
296f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
297f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
298fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::~SensorService()
299fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
300f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    for (size_t i=0 ; i<mSensorMap.size() ; i++)
301f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        delete mSensorMap.valueAt(i);
302fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
303fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
3044949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akellastatus_t SensorService::dump(int fd, const Vector<String16>& args)
305fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
306fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    String8 result;
3071cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
308eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu        result.appendFormat("Permission Denial: can't dump SensorService from pid=%d, uid=%d\n",
309fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian                IPCThreadState::self()->getCallingPid(),
310fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian                IPCThreadState::self()->getCallingUid());
311444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    } else {
312841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella        if (args.size() > 2) {
3134949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella           return INVALID_OPERATION;
3144949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        }
3154949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        Mutex::Autolock _l(mLock);
3164949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        SensorDevice& dev(SensorDevice::getInstance());
317841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella        if (args.size() == 2 && args[0] == String16("restrict")) {
318444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            // If already in restricted mode. Ignore.
319444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            if (mCurrentOperatingMode == RESTRICTED) {
320444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                return status_t(NO_ERROR);
321444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            }
322444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            // If in any mode other than normal, ignore.
323444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            if (mCurrentOperatingMode != NORMAL) {
324444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                return INVALID_OPERATION;
325444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            }
326a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella            mCurrentOperatingMode = RESTRICTED;
3274949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            dev.disableAllSensors();
3284949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            // Clear all pending flush connections for all active sensors. If one of the active
3294949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            // connections has called flush() and the underlying sensor has been disabled before a
3304949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            // flush complete event is returned, we need to remove the connection from this queue.
3314949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            for (size_t i=0 ; i< mActiveSensors.size(); ++i) {
3324949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella                mActiveSensors.valueAt(i)->clearAllPendingFlushConnections();
3334949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            }
334841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            mWhiteListedPackage.setTo(String8(args[1]));
335444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            return status_t(NO_ERROR);
336444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        } else if (args.size() == 1 && args[0] == String16("enable")) {
337444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            // If currently in restricted mode, reset back to NORMAL mode else ignore.
338444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            if (mCurrentOperatingMode == RESTRICTED) {
339444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                mCurrentOperatingMode = NORMAL;
340444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                dev.enableAllSensors();
3416c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            }
342841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            if (mCurrentOperatingMode == DATA_INJECTION) {
343841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella               resetToNormalModeLocked();
344841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            }
345841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            mWhiteListedPackage.clear();
346444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            return status_t(NO_ERROR);
347841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella        } else if (args.size() == 2 && args[0] == String16("data_injection")) {
348841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            if (mCurrentOperatingMode == NORMAL) {
349841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                dev.disableAllSensors();
350841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                status_t err = dev.setMode(DATA_INJECTION);
351841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                if (err == NO_ERROR) {
352841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                    mCurrentOperatingMode = DATA_INJECTION;
353841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                } else {
354841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                    // Re-enable sensors.
355841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                    dev.enableAllSensors();
356841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                }
357841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                mWhiteListedPackage.setTo(String8(args[1]));
358841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                return NO_ERROR;
359841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            } else if (mCurrentOperatingMode == DATA_INJECTION) {
360841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                // Already in DATA_INJECTION mode. Treat this as a no_op.
361841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                return NO_ERROR;
362841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            } else {
363841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                // Transition to data injection mode supported only from NORMAL mode.
364841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                return INVALID_OPERATION;
365841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            }
366ee155cadb23e84542cbf445c2aac89ae63df4cc7Aravind Akella        } else if (mSensorList.size() == 0) {
367ee155cadb23e84542cbf445c2aac89ae63df4cc7Aravind Akella            result.append("No Sensors on the device\n");
368444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        } else {
369444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            // Default dump the sensor list and debugging information.
370444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            result.append("Sensor List:\n");
371444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            for (size_t i=0 ; i<mSensorList.size() ; i++) {
372444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                const Sensor& s(mSensorList[i]);
373444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                result.appendFormat(
374444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        "%-15s| %-10s| version=%d |%-20s| 0x%08x | \"%s\" | type=%d |",
375444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        s.getName().string(),
376444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        s.getVendor().string(),
377444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        s.getVersion(),
378444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        s.getStringType().string(),
379444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        s.getHandle(),
380444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        s.getRequiredPermission().string(),
381444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        s.getType());
382444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella
383444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                const int reportingMode = s.getReportingMode();
384444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                if (reportingMode == AREPORTING_MODE_CONTINUOUS) {
385444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.append(" continuous | ");
386444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                } else if (reportingMode == AREPORTING_MODE_ON_CHANGE) {
387444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.append(" on-change | ");
388444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                } else if (reportingMode == AREPORTING_MODE_ONE_SHOT) {
389444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.append(" one-shot | ");
390444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                } else {
391444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.append(" special-trigger | ");
392444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                }
3936c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
394444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                if (s.getMaxDelay() > 0) {
395444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.appendFormat("minRate=%.2fHz | ", 1e6f / s.getMaxDelay());
396444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                } else {
397444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.appendFormat("maxDelay=%dus |", s.getMaxDelay());
398444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                }
3990e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella
400444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                if (s.getMinDelay() > 0) {
401444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.appendFormat("maxRate=%.2fHz | ", 1e6f / s.getMinDelay());
402444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                } else {
403444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.appendFormat("minDelay=%dus |", s.getMinDelay());
404444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                }
4050e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella
406444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                if (s.getFifoMaxEventCount() > 0) {
407444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.appendFormat("FifoMax=%d events | ",
408444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                            s.getFifoMaxEventCount());
409444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                } else {
410444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.append("no batching | ");
411444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                }
4126c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
413444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                if (s.isWakeUpSensor()) {
414444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.appendFormat("wakeUp | ");
415444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                } else {
416444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.appendFormat("non-wakeUp | ");
417444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                }
418ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian
41918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                int bufIndex = mLastEventSeen.indexOfKey(s.getHandle());
42018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                if (bufIndex >= 0) {
421eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu                    const MostRecentEventLogger* buf = mLastEventSeen.valueAt(bufIndex);
42218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                    if (buf != NULL && s.getRequiredPermission().isEmpty()) {
42318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                        buf->printBuffer(result);
42418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                    } else {
42518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                        result.append("last=<> \n");
42618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                    }
427444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                }
428444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                result.append("\n");
429444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            }
430444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            SensorFusion::getInstance().dump(result);
431444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            SensorDevice::getInstance().dump(result);
432444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella
433444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            result.append("Active sensors:\n");
434444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            for (size_t i=0 ; i<mActiveSensors.size() ; i++) {
435444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                int handle = mActiveSensors.keyAt(i);
436444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                result.appendFormat("%s (handle=0x%08x, connections=%zu)\n",
437444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        getSensorName(handle).string(),
438444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        handle,
439444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        mActiveSensors.valueAt(i)->getNumConnections());
440ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            }
4414c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
442d4036b6b7f9609fe09efabdbfbb8c8f9428f76f7Andreas Gampe            result.appendFormat("Socket Buffer size = %zd events\n",
443444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                                mSocketBufferSize/sizeof(sensors_event_t));
44418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            result.appendFormat("WakeLock Status: %s \n", mWakeLockAcquired ? "acquired" :
44518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                    "not held");
446444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            result.appendFormat("Mode :");
447444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            switch(mCurrentOperatingMode) {
448444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella               case NORMAL:
449444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                   result.appendFormat(" NORMAL\n");
450444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                   break;
451444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella               case RESTRICTED:
452841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                   result.appendFormat(" RESTRICTED : %s\n", mWhiteListedPackage.string());
453444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                   break;
454444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella               case DATA_INJECTION:
455841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                   result.appendFormat(" DATA_INJECTION : %s\n", mWhiteListedPackage.string());
456444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            }
457444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            result.appendFormat("%zd active connections\n", mActiveConnections.size());
4584c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
459444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            for (size_t i=0 ; i < mActiveConnections.size() ; i++) {
460444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                sp<SensorEventConnection> connection(mActiveConnections[i].promote());
461444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                if (connection != 0) {
462444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.appendFormat("Connection Number: %zu \n", i);
463444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    connection->dump(result);
464444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                }
4654c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
46618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella
46718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            result.appendFormat("Previous Registrations:\n");
46818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            // Log in the reverse chronological order.
46918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            int currentIndex = (mNextSensorRegIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) %
47018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                SENSOR_REGISTRATIONS_BUF_SIZE;
47118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            const int startIndex = currentIndex;
47218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            do {
47318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                const SensorRegistrationInfo& reg_info = mLastNSensorRegistrations[currentIndex];
47418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                if (SensorRegistrationInfo::isSentinel(reg_info)) {
47518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                    // Ignore sentinel, proceed to next item.
47618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                    currentIndex = (currentIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) %
47718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                        SENSOR_REGISTRATIONS_BUF_SIZE;
47818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                    continue;
47918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                }
48018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                if (reg_info.mActivated) {
48118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                   result.appendFormat("%02d:%02d:%02d activated package=%s handle=0x%08x "
48218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                           "samplingRate=%dus maxReportLatency=%dus\n",
48318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                           reg_info.mHour, reg_info.mMin, reg_info.mSec,
48418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                           reg_info.mPackageName.string(), reg_info.mSensorHandle,
48518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                           reg_info.mSamplingRateUs, reg_info.mMaxReportLatencyUs);
48618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                } else {
48718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                   result.appendFormat("%02d:%02d:%02d de-activated package=%s handle=0x%08x\n",
48818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                           reg_info.mHour, reg_info.mMin, reg_info.mSec,
48918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                           reg_info.mPackageName.string(), reg_info.mSensorHandle);
49018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                }
49118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                currentIndex = (currentIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) %
49218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                        SENSOR_REGISTRATIONS_BUF_SIZE;
49318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            } while(startIndex != currentIndex);
4944c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
495fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
496fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    write(fd, result.string(), result.size());
497fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return NO_ERROR;
498fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
499fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
5009a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::cleanupAutoDisabledSensorLocked(const sp<SensorEventConnection>& connection,
5014342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        sensors_event_t const* buffer, const int count) {
5024342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    for (int i=0 ; i<count ; i++) {
5034342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        int handle = buffer[i].sensor;
5048493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        if (buffer[i].type == SENSOR_TYPE_META_DATA) {
5058493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            handle = buffer[i].meta_data.sensor;
5068493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        }
5070e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella        if (connection->hasSensor(handle)) {
5080e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            SensorInterface* sensor = mSensorMap.valueFor(handle);
5090e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            // If this buffer has an event from a one_shot sensor and this connection is registered
5100e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            // for this particular one_shot sensor, try cleaning up the connection.
5110e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            if (sensor != NULL &&
5120e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella                sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
5130e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella                sensor->autoDisable(connection.get(), handle);
5149a844cf78f09953145200b4074d47589257a408cAravind Akella                cleanupWithoutDisableLocked(connection, handle);
5154342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            }
516a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
5174342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
518a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella   }
5194342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh}
5204342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
521fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::threadLoop()
522fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
523a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block    ALOGD("nuSensorService thread starting...");
524fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
525eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu    // each virtual sensor could generate an event per "real" event, that's why we need to size
526eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu    // numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT.  in practice, this is too
527eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu    // aggressive, but guaranteed to be enough.
52890ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
52990ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    const size_t numEventMax = minBufferSize / (1 + mVirtualSensorList.size());
53090ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian
531f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    SensorDevice& device(SensorDevice::getInstance());
532f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    const size_t vcount = mVirtualSensorList.size();
533fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
5344342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    const int halVersion = device.getHalDeviceVersion();
535fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    do {
5368493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
5378493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        if (count < 0) {
538f5a1230d322c14c42331d0a1536b50c87742973bSteve Block            ALOGE("sensor poll failed (%s)", strerror(-count));
539fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            break;
540fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
54156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
54256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        // Reset sensors_event_t.flags to zero for all events in the buffer.
54356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        for (int i = 0; i < count; i++) {
5448493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella             mSensorEventBuffer[i].flags = 0;
54556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        }
546e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella
547eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu        // Make a copy of the connection vector as some connections may be removed during the course
548eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu        // of this loop (especially when one-shot sensor events are present in the sensor_event
549eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu        // buffer). Promote all connections to StrongPointers before the lock is acquired. If the
550eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu        // destructor of the sp gets called when the lock is acquired, it may result in a deadlock
551eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu        // as ~SensorEventConnection() needs to acquire mLock again for cleanup. So copy all the
552eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu        // strongPointers to a vector before the lock is acquired.
553e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella        SortedVector< sp<SensorEventConnection> > activeConnections;
554b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        populateActiveConnections(&activeConnections);
555eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu
5569a844cf78f09953145200b4074d47589257a408cAravind Akella        Mutex::Autolock _l(mLock);
5579a844cf78f09953145200b4074d47589257a408cAravind Akella        // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The
5589a844cf78f09953145200b4074d47589257a408cAravind Akella        // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock,
5599a844cf78f09953145200b4074d47589257a408cAravind Akella        // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should
5609a844cf78f09953145200b4074d47589257a408cAravind Akella        // not be interleaved with decrementing SensorEventConnection::mWakeLockRefCount and
5619a844cf78f09953145200b4074d47589257a408cAravind Akella        // releasing the wakelock.
5629a844cf78f09953145200b4074d47589257a408cAravind Akella        bool bufferHasWakeUpEvent = false;
5634342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        for (int i = 0; i < count; i++) {
5648493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            if (isWakeUpSensorEvent(mSensorEventBuffer[i])) {
5659a844cf78f09953145200b4074d47589257a408cAravind Akella                bufferHasWakeUpEvent = true;
5669a844cf78f09953145200b4074d47589257a408cAravind Akella                break;
5674342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            }
5684342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
5694342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
5709a844cf78f09953145200b4074d47589257a408cAravind Akella        if (bufferHasWakeUpEvent && !mWakeLockAcquired) {
571b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            setWakeLockAcquiredLocked(true);
5729a844cf78f09953145200b4074d47589257a408cAravind Akella        }
5738493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        recordLastValueLocked(mSensorEventBuffer, count);
57494e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian
575f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        // handle virtual sensors
576f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        if (count && vcount) {
5778493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            sensors_event_t const * const event = mSensorEventBuffer;
5789a844cf78f09953145200b4074d47589257a408cAravind Akella            const size_t activeVirtualSensorCount = mActiveVirtualSensors.size();
579f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            if (activeVirtualSensorCount) {
580f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                size_t k = 0;
581984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                SensorFusion& fusion(SensorFusion::getInstance());
582984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                if (fusion.isEnabled()) {
583984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                    for (size_t i=0 ; i<size_t(count) ; i++) {
584984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                        fusion.process(event[i]);
585984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                    }
586984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                }
587d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) {
588f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {
589d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                        if (count + k >= minBufferSize) {
590d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                            ALOGE("buffer too small to hold all events: "
591db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn                                    "count=%zd, k=%zu, size=%zu",
592d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                                    count, k, minBufferSize);
593d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                            break;
594d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                        }
595f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                        sensors_event_t out;
5969a844cf78f09953145200b4074d47589257a408cAravind Akella                        SensorInterface* si = mActiveVirtualSensors.valueAt(j);
597d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                        if (si->process(&out, event[i])) {
5988493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                            mSensorEventBuffer[count + k] = out;
599f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                            k++;
600f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                        }
601f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    }
602f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                }
603f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                if (k) {
604f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    // record the last synthesized values
6058493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    recordLastValueLocked(&mSensorEventBuffer[count], k);
606f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    count += k;
607f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    // sort the buffer by time-stamps
6088493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    sortEventBuffer(mSensorEventBuffer, count);
609f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                }
610f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            }
611f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        }
612f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
6134342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // handle backward compatibility for RotationVector sensor
6144342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) {
6154342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            for (int i = 0; i < count; i++) {
6168493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                if (mSensorEventBuffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) {
6174342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                    // All the 4 components of the quaternion should be available
6184342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                    // No heading accuracy. Set it to -1
6198493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    mSensorEventBuffer[i].data[4] = -1;
6208493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                }
6218493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            }
6228493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        }
6238493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella
6248493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        for (int i = 0; i < count; ++i) {
6252576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            // Map flush_complete_events in the buffer to SensorEventConnections which called flush on
6262576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            // the hardware sensor. mapFlushEventsToConnections[i] will be the SensorEventConnection
6272576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            // mapped to the corresponding flush_complete_event in mSensorEventBuffer[i] if such a
6282576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            // mapping exists (NULL otherwise).
6298493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            mMapFlushEventsToConnections[i] = NULL;
6308493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            if (mSensorEventBuffer[i].type == SENSOR_TYPE_META_DATA) {
6318493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                const int sensor_handle = mSensorEventBuffer[i].meta_data.sensor;
6328493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                SensorRecord* rec = mActiveSensors.valueFor(sensor_handle);
6338493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                if (rec != NULL) {
6348493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    mMapFlushEventsToConnections[i] = rec->getFirstPendingFlushConnection();
6358493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    rec->removeFirstPendingFlushConnection();
6364342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                }
6374342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            }
6382576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
6392576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            // handle dynamic sensor meta events, process registration and unregistration of dynamic
6402576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            // sensor based on content of event.
6412576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            if (mSensorEventBuffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META) {
6422576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                if (mSensorEventBuffer[i].dynamic_sensor_meta.connected) {
6432576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    int handle = mSensorEventBuffer[i].dynamic_sensor_meta.handle;
6442576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    const sensor_t& dynamicSensor =
6452576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                            *(mSensorEventBuffer[i].dynamic_sensor_meta.sensor);
6462576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    ALOGI("Dynamic sensor handle 0x%x connected, type %d, name %s",
6472576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                          handle, dynamicSensor.type, dynamicSensor.name);
6482576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
6492576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    device.handleDynamicSensorConnection(handle, true /*connected*/);
6502576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    registerDynamicSensor(new HardwareSensor(dynamicSensor));
6512576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
6522576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                } else {
6532576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    int handle = mSensorEventBuffer[i].dynamic_sensor_meta.handle;
6542576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    ALOGI("Dynamic sensor handle 0x%x disconnected", handle);
6552576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
6562576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    device.handleDynamicSensorConnection(handle, false /*connected*/);
6572576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    if (!unregisterDynamicSensor(handle)) {
6582576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                        ALOGE("Dynamic sensor release error.");
6592576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    }
6602576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
6612576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    size_t numConnections = activeConnections.size();
6622576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    for (size_t i=0 ; i < numConnections; ++i) {
6632576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                        if (activeConnections[i] != NULL) {
6642576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                            activeConnections[i]->removeSensor(handle);
6652576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                        }
6662576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    }
6672576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                }
6682576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            }
6694342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
6704342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
6712576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
6729a844cf78f09953145200b4074d47589257a408cAravind Akella        // Send our events to clients. Check the state of wake lock for each client and release the
6739a844cf78f09953145200b4074d47589257a408cAravind Akella        // lock if none of the clients need it.
6749a844cf78f09953145200b4074d47589257a408cAravind Akella        bool needsWakeLock = false;
6758493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        size_t numConnections = activeConnections.size();
6768493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        for (size_t i=0 ; i < numConnections; ++i) {
677e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella            if (activeConnections[i] != 0) {
678e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella                activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,
6798493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                        mMapFlushEventsToConnections);
680e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella                needsWakeLock |= activeConnections[i]->needsWakeLock();
6818493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                // If the connection has one-shot sensors, it may be cleaned up after first trigger.
6828493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                // Early check for one-shot sensors.
683e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella                if (activeConnections[i]->hasOneShotSensors()) {
684e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella                    cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer,
685e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella                            count);
6868493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                }
687fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            }
688fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
6894342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
6909a844cf78f09953145200b4074d47589257a408cAravind Akella        if (mWakeLockAcquired && !needsWakeLock) {
691b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            setWakeLockAcquiredLocked(false);
6929a844cf78f09953145200b4074d47589257a408cAravind Akella        }
6938493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella    } while (!Thread::exitPending());
694fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
6953c20fbed7f3a916ced10f2ed5a272271b7d81edeSteve Block    ALOGW("Exiting SensorService::threadLoop => aborting...");
6961a62301fc58cd2af18239b0415813461bf5fc41bMathias Agopian    abort();
697fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return false;
698fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
699fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
70056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellasp<Looper> SensorService::getLooper() const {
70156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    return mLooper;
70256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella}
70356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
704b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::resetAllWakeLockRefCounts() {
705b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    SortedVector< sp<SensorEventConnection> > activeConnections;
706b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    populateActiveConnections(&activeConnections);
707b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    {
708b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        Mutex::Autolock _l(mLock);
709b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        for (size_t i=0 ; i < activeConnections.size(); ++i) {
710b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            if (activeConnections[i] != 0) {
711b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella                activeConnections[i]->resetWakeLockRefCount();
712b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            }
713b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        }
714b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        setWakeLockAcquiredLocked(false);
715b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    }
716b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
717b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
718b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::setWakeLockAcquiredLocked(bool acquire) {
719b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    if (acquire) {
720b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        if (!mWakeLockAcquired) {
721b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
722b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            mWakeLockAcquired = true;
723b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        }
724b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        mLooper->wake();
725b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    } else {
726b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        if (mWakeLockAcquired) {
727b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            release_wake_lock(WAKE_LOCK_NAME);
728b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            mWakeLockAcquired = false;
729b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        }
730b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    }
731b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
732b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
733b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellabool SensorService::isWakeLockAcquired() {
734b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    Mutex::Autolock _l(mLock);
735b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    return mWakeLockAcquired;
736b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
737b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
73856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellabool SensorService::SensorEventAckReceiver::threadLoop() {
73956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    ALOGD("new thread SensorEventAckReceiver");
740b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    sp<Looper> looper = mService->getLooper();
74156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    do {
742b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        bool wakeLockAcquired = mService->isWakeLockAcquired();
743b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        int timeout = -1;
744b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        if (wakeLockAcquired) timeout = 5000;
745b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        int ret = looper->pollOnce(timeout);
746b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        if (ret == ALOOPER_POLL_TIMEOUT) {
747b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella           mService->resetAllWakeLockRefCounts();
748b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        }
74956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    } while(!Thread::exitPending());
75056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    return false;
75156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella}
75256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
7539a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::recordLastValueLocked(
7544b84704b97300eff3ebfab85652e64d54149d205Aravind Akella        const sensors_event_t* buffer, size_t count) {
7554b84704b97300eff3ebfab85652e64d54149d205Aravind Akella    for (size_t i = 0; i < count; i++) {
7562576cb63b3fe1592f54816625036566b9eb0793aPeng Xu        if (buffer[i].type == SENSOR_TYPE_META_DATA ||
7572576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            buffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META ||
7582576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            mLastEventSeen.indexOfKey(buffer[i].sensor) <0 ) {
7592576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            continue;
7602576cb63b3fe1592f54816625036566b9eb0793aPeng Xu        }
7612576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
7622576cb63b3fe1592f54816625036566b9eb0793aPeng Xu        MostRecentEventLogger* &circular_buf = mLastEventSeen.editValueFor(buffer[i].sensor);
7632576cb63b3fe1592f54816625036566b9eb0793aPeng Xu        if (circular_buf == NULL) {
7642576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            circular_buf = new MostRecentEventLogger(buffer[i].type);
76594e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian        }
7662576cb63b3fe1592f54816625036566b9eb0793aPeng Xu        circular_buf->addEvent(buffer[i]);
76794e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian    }
76894e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian}
76994e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian
770f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopianvoid SensorService::sortEventBuffer(sensors_event_t* buffer, size_t count)
771f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{
772f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    struct compar {
773f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        static int cmp(void const* lhs, void const* rhs) {
774f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            sensors_event_t const* l = static_cast<sensors_event_t const*>(lhs);
775f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            sensors_event_t const* r = static_cast<sensors_event_t const*>(rhs);
776a5c106a4f0afcf061728a1cb7c8c3b908728575dMathias Agopian            return l->timestamp - r->timestamp;
777f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        }
778f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    };
779f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    qsort(buffer, count, sizeof(sensors_event_t), compar::cmp);
780f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
781f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
7825d2707214dfb97bd8dfcc6620be36841d3c82420Mathias AgopianString8 SensorService::getSensorName(int handle) const {
783010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian    size_t count = mUserSensorList.size();
7845d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
785010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian        const Sensor& sensor(mUserSensorList[i]);
7865d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian        if (sensor.getHandle() == handle) {
7875d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian            return sensor.getName();
7885d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian        }
7895d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian    }
7905d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian    String8 result("unknown");
7915d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian    return result;
7925d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian}
7935d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian
794b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akellabool SensorService::isVirtualSensor(int handle) const {
795b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella    SensorInterface* sensor = mSensorMap.valueFor(handle);
7962576cb63b3fe1592f54816625036566b9eb0793aPeng Xu    return sensor != NULL && sensor->isVirtual();
797b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella}
798b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella
7999a844cf78f09953145200b4074d47589257a408cAravind Akellabool SensorService::isWakeUpSensorEvent(const sensors_event_t& event) const {
8007869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan    int handle = event.sensor;
8017869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan    if (event.type == SENSOR_TYPE_META_DATA) {
8027869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan        handle = event.meta_data.sensor;
8037869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan    }
8047869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan    SensorInterface* sensor = mSensorMap.valueFor(handle);
8057869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan    return sensor != NULL && sensor->getSensor().isWakeUpSensor();
8069a844cf78f09953145200b4074d47589257a408cAravind Akella}
8079a844cf78f09953145200b4074d47589257a408cAravind Akella
8086c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind AkellaSensorService::SensorRecord * SensorService::getSensorRecord(int handle) {
8096c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella     return mActiveSensors.valueFor(handle);
8106c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella}
8116c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
812b412f6e203b38f8047f760261a5e3dc6d0722f08SvetoslavVector<Sensor> SensorService::getSensorList(const String16& opPackageName)
813fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
81433264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian    char value[PROPERTY_VALUE_MAX];
81533264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian    property_get("debug.sensors", value, "0");
816700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    const Vector<Sensor>& initialSensorList = (atoi(value)) ?
817700180487ffec09d9df1657b018a7caadac24b75Aravind Akella            mUserSensorListDebug : mUserSensorList;
818700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    Vector<Sensor> accessibleSensorList;
819700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    for (size_t i = 0; i < initialSensorList.size(); i++) {
820700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        Sensor sensor = initialSensorList[i];
821b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        if (canAccessSensor(sensor, "getSensorList", opPackageName)) {
822700180487ffec09d9df1657b018a7caadac24b75Aravind Akella            accessibleSensorList.add(sensor);
823700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        } else {
824b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            ALOGI("Skipped sensor %s because it requires permission %s and app op %d",
8255f6199373dc1e07d2ee5edbae7ecfa08a065492eBernhard Rosenkränzer                  sensor.getName().string(),
826b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                  sensor.getRequiredPermission().string(),
827b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                  sensor.getRequiredAppOp());
828700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        }
82933264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian    }
830700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    return accessibleSensorList;
831fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
832fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
8332576cb63b3fe1592f54816625036566b9eb0793aPeng XuVector<Sensor> SensorService::getDynamicSensorList(const String16& opPackageName)
8342576cb63b3fe1592f54816625036566b9eb0793aPeng Xu{
8352576cb63b3fe1592f54816625036566b9eb0793aPeng Xu    Vector<Sensor> accessibleSensorList;
8362576cb63b3fe1592f54816625036566b9eb0793aPeng Xu    for (size_t i = 0; i < mDynamicSensorList.size(); i++) {
8372576cb63b3fe1592f54816625036566b9eb0793aPeng Xu        Sensor sensor = mDynamicSensorList[i];
8382576cb63b3fe1592f54816625036566b9eb0793aPeng Xu        if (canAccessSensor(sensor, "getDynamicSensorList", opPackageName)) {
8392576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            accessibleSensorList.add(sensor);
8402576cb63b3fe1592f54816625036566b9eb0793aPeng Xu        } else {
8412576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            ALOGI("Skipped sensor %s because it requires permission %s and app op %d",
8422576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                  sensor.getName().string(),
8432576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                  sensor.getRequiredPermission().string(),
8442576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                  sensor.getRequiredAppOp());
8452576cb63b3fe1592f54816625036566b9eb0793aPeng Xu        }
8462576cb63b3fe1592f54816625036566b9eb0793aPeng Xu    }
8472576cb63b3fe1592f54816625036566b9eb0793aPeng Xu    return accessibleSensorList;
8482576cb63b3fe1592f54816625036566b9eb0793aPeng Xu}
8492576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
850a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellasp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName,
851b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        int requestedMode, const String16& opPackageName) {
852a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    // Only 2 modes supported for a SensorEventConnection ... NORMAL and DATA_INJECTION.
853a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    if (requestedMode != NORMAL && requestedMode != DATA_INJECTION) {
854a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        return NULL;
855a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    }
856a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
857a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    Mutex::Autolock _l(mLock);
858841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    // To create a client in DATA_INJECTION mode to inject data, SensorService should already be
859841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    // operating in DI mode.
860841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    if (requestedMode == DATA_INJECTION) {
861841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella        if (mCurrentOperatingMode != DATA_INJECTION) return NULL;
862841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella        if (!isWhiteListedPackage(packageName)) return NULL;
863841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    }
864841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella
8655307d17fe33fc26eeeacd6339a9fbfe96cf56873Mathias Agopian    uid_t uid = IPCThreadState::self()->getCallingUid();
866a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    sp<SensorEventConnection> result(new SensorEventConnection(this, uid, packageName,
867b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            requestedMode == DATA_INJECTION, opPackageName));
868a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    if (requestedMode == DATA_INJECTION) {
869a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        if (mActiveConnections.indexOf(result) < 0) {
870a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella            mActiveConnections.add(result);
871a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        }
872a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        // Add the associated file descriptor to the Looper for polling whenever there is data to
873a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        // be injected.
874a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        result->updateLooperRegistration(mLooper);
875a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    }
876fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return result;
877fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
878fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
879841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akellaint SensorService::isDataInjectionEnabled() {
880a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    Mutex::Autolock _l(mLock);
881841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    return (mCurrentOperatingMode == DATA_INJECTION);
882a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella}
883a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
884a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatus_t SensorService::resetToNormalMode() {
885a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    Mutex::Autolock _l(mLock);
886a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    return resetToNormalModeLocked();
887a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella}
888a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
889a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatus_t SensorService::resetToNormalModeLocked() {
890a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    SensorDevice& dev(SensorDevice::getInstance());
891a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    dev.enableAllSensors();
892a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    status_t err = dev.setMode(NORMAL);
893a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    mCurrentOperatingMode = NORMAL;
894a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    return err;
895a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella}
896a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
897db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopianvoid SensorService::cleanupConnection(SensorEventConnection* c)
898fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
899fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    Mutex::Autolock _l(mLock);
900db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian    const wp<SensorEventConnection> connection(c);
9017c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    size_t size = mActiveSensors.size();
902db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn    ALOGD_IF(DEBUG_CONNECTIONS, "%zu active sensors", size);
9037c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    for (size_t i=0 ; i<size ; ) {
904db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        int handle = mActiveSensors.keyAt(i);
905db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        if (c->hasSensor(handle)) {
906db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn            ALOGD_IF(DEBUG_CONNECTIONS, "%zu: disabling handle=0x%08x", i, handle);
907f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            SensorInterface* sensor = mSensorMap.valueFor( handle );
908f5a1230d322c14c42331d0a1536b50c87742973bSteve Block            ALOGE_IF(!sensor, "mSensorMap[handle=0x%08x] is null!", handle);
909f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            if (sensor) {
910db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian                sensor->activate(c, false);
911f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            }
9128a96955c8e14db40b16164236830fc9506a00872Aravind Akella            c->removeSensor(handle);
913db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        }
914db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        SensorRecord* rec = mActiveSensors.valueAt(i);
915db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn        ALOGE_IF(!rec, "mActiveSensors[%zu] is null (handle=0x%08x)!", i, handle);
916a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block        ALOGD_IF(DEBUG_CONNECTIONS,
917db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn                "removing connection %p for sensor[%zu].handle=0x%08x",
918a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian                c, i, handle);
919a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian
920db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        if (rec && rec->removeConnection(connection)) {
921a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block            ALOGD_IF(DEBUG_CONNECTIONS, "... and it was the last connection");
9227c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            mActiveSensors.removeItemsAt(i, 1);
923f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            mActiveVirtualSensors.removeItem(handle);
9247c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            delete rec;
9257c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            size--;
9267c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian        } else {
9277c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            i++;
928fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
929fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
9308a96955c8e14db40b16164236830fc9506a00872Aravind Akella    c->updateLooperRegistration(mLooper);
9317c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    mActiveConnections.remove(connection);
932787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian    BatteryService::cleanup(c->getUid());
9339a844cf78f09953145200b4074d47589257a408cAravind Akella    if (c->needsWakeLock()) {
9349a844cf78f09953145200b4074d47589257a408cAravind Akella        checkWakeLockStateLocked();
9359a844cf78f09953145200b4074d47589257a408cAravind Akella    }
936fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
937fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
938700180487ffec09d9df1657b018a7caadac24b75Aravind AkellaSensor SensorService::getSensorFromHandle(int handle) const {
939700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    return mSensorMap.valueFor(handle)->getSensor();
940700180487ffec09d9df1657b018a7caadac24b75Aravind Akella}
941700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
942fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::enable(const sp<SensorEventConnection>& connection,
943b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags,
944b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        const String16& opPackageName)
945fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
94650df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian    if (mInitCheck != NO_ERROR)
94750df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian        return mInitCheck;
94850df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
949f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    SensorInterface* sensor = mSensorMap.valueFor(handle);
950ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    if (sensor == NULL) {
951ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        return BAD_VALUE;
952ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    }
953700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
954b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (!canAccessSensor(sensor->getSensor(), "Tried enabling", opPackageName)) {
955700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return BAD_VALUE;
956700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
957700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
958ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    Mutex::Autolock _l(mLock);
959841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    if ((mCurrentOperatingMode == RESTRICTED || mCurrentOperatingMode == DATA_INJECTION)
960841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella           && !isWhiteListedPackage(connection->getPackageName())) {
9614949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        return INVALID_OPERATION;
9624949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    }
9634949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
9644342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    SensorRecord* rec = mActiveSensors.valueFor(handle);
9654342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (rec == 0) {
9664342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        rec = new SensorRecord(connection);
9674342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        mActiveSensors.add(handle, rec);
9684342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (sensor->isVirtual()) {
9694342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            mActiveVirtualSensors.add(handle, sensor);
9703560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        }
9714342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    } else {
9724342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (rec->addConnection(connection)) {
9739a844cf78f09953145200b4074d47589257a408cAravind Akella            // this sensor is already activated, but we are adding a connection that uses it.
9749a844cf78f09953145200b4074d47589257a408cAravind Akella            // Immediately send down the last known value of the requested sensor if it's not a
9754342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            // "continuous" sensor.
9760e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ON_CHANGE) {
9779a844cf78f09953145200b4074d47589257a408cAravind Akella                // NOTE: The wake_up flag of this event may get set to
9789a844cf78f09953145200b4074d47589257a408cAravind Akella                // WAKE_UP_SENSOR_EVENT_NEEDS_ACK if this is a wake_up event.
979eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu                MostRecentEventLogger *circular_buf = mLastEventSeen.valueFor(handle);
980444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                if (circular_buf) {
981444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    sensors_event_t event;
982444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    memset(&event, 0, sizeof(event));
983444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    // It is unlikely that this buffer is empty as the sensor is already active.
984444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    // One possible corner case may be two applications activating an on-change
985444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    // sensor at the same time.
986444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    if(circular_buf->populateLastEvent(&event)) {
987444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        event.sensor = handle;
988444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        if (event.version == sizeof(sensors_event_t)) {
989444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                            if (isWakeUpSensorEvent(event) && !mWakeLockAcquired) {
990444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                                setWakeLockAcquiredLocked(true);
991444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                            }
992444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                            connection->sendEvents(&event, 1, NULL);
993444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                            if (!connection->needsWakeLock() && mWakeLockAcquired) {
994444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                                checkWakeLockStateLocked();
995444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                            }
996444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        }
9979a844cf78f09953145200b4074d47589257a408cAravind Akella                    }
998f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                }
9997c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            }
1000fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
1001fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
10024342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
10034342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (connection->addSensor(handle)) {
10044342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        BatteryService::enableSensor(connection->getUid(), handle);
10054342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // the sensor was added (which means it wasn't already there)
10064342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // so, see if this connection becomes active
10074342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (mActiveConnections.indexOf(connection) < 0) {
10084342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            mActiveConnections.add(connection);
10094342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
10104342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    } else {
10114342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        ALOGW("sensor %08x already enabled in connection %p (ignoring)",
10124342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            handle, connection.get());
10134342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
10144342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
1015724d91d778e71c8186399f4955de14b54812b3edAravind Akella    nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
1016724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (samplingPeriodNs < minDelayNs) {
1017724d91d778e71c8186399f4955de14b54812b3edAravind Akella        samplingPeriodNs = minDelayNs;
1018724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
1019724d91d778e71c8186399f4955de14b54812b3edAravind Akella
10206c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d"
10216c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                                "rate=%" PRId64 " timeout== %" PRId64"",
1022724d91d778e71c8186399f4955de14b54812b3edAravind Akella             handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs);
1023724d91d778e71c8186399f4955de14b54812b3edAravind Akella
10244949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    status_t err = sensor->batch(connection.get(), handle, 0, samplingPeriodNs,
1025724d91d778e71c8186399f4955de14b54812b3edAravind Akella                                 maxBatchReportLatencyNs);
10266c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
102720483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu    // Call flush() before calling activate() on the sensor. Wait for a first
102820483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu    // flush complete event before sending events on this connection. Ignore
102920483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu    // one-shot sensors which don't support flush(). Ignore on-change sensors
103020483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu    // to maintain the on-change logic (any on-change events except the initial
103120483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu    // one should be trigger by a change in value). Also if this sensor isn't
103220483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu    // already active, don't call flush().
103320483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu    if (err == NO_ERROR &&
10342576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            sensor->getSensor().getReportingMode() == AREPORTING_MODE_CONTINUOUS &&
10355466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            rec->getNumConnections() > 1) {
10365466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella        connection->setFirstFlushPending(handle, true);
10374c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        status_t err_flush = sensor->flush(connection.get(), handle);
10385466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella        // Flush may return error if the underlying h/w sensor uses an older HAL.
10396c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        if (err_flush == NO_ERROR) {
10406c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            rec->addPendingFlushConnection(connection.get());
10415466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella        } else {
10425466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            connection->setFirstFlushPending(handle, false);
10434c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
10444c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
1045724d91d778e71c8186399f4955de14b54812b3edAravind Akella
1046724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (err == NO_ERROR) {
1047724d91d778e71c8186399f4955de14b54812b3edAravind Akella        ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle);
1048724d91d778e71c8186399f4955de14b54812b3edAravind Akella        err = sensor->activate(connection.get(), true);
1049724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
1050724d91d778e71c8186399f4955de14b54812b3edAravind Akella
10518a96955c8e14db40b16164236830fc9506a00872Aravind Akella    if (err == NO_ERROR) {
10528a96955c8e14db40b16164236830fc9506a00872Aravind Akella        connection->updateLooperRegistration(mLooper);
105318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        SensorRegistrationInfo &reg_info =
105418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex);
105518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mSensorHandle = handle;
105618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mSamplingRateUs = samplingPeriodNs/1000;
105718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mMaxReportLatencyUs = maxBatchReportLatencyNs/1000;
105818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mActivated = true;
105918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mPackageName = connection->getPackageName();
106018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        time_t rawtime = time(NULL);
106118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        struct tm * timeinfo = localtime(&rawtime);
106218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mHour = timeinfo->tm_hour;
106318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mMin = timeinfo->tm_min;
106418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mSec = timeinfo->tm_sec;
106518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        mNextSensorRegIndex = (mNextSensorRegIndex + 1) % SENSOR_REGISTRATIONS_BUF_SIZE;
106656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    }
106756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
10684342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (err != NO_ERROR) {
1069724d91d778e71c8186399f4955de14b54812b3edAravind Akella        // batch/activate has failed, reset our state.
1070ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        cleanupWithoutDisableLocked(connection, handle);
10714342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
1072fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return err;
1073fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1074fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1075fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::disable(const sp<SensorEventConnection>& connection,
1076fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        int handle)
1077fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
107850df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian    if (mInitCheck != NO_ERROR)
107950df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian        return mInitCheck;
108050df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
1081ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    Mutex::Autolock _l(mLock);
1082ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    status_t err = cleanupWithoutDisableLocked(connection, handle);
10834342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (err == NO_ERROR) {
10844342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        SensorInterface* sensor = mSensorMap.valueFor(handle);
10854342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        err = sensor ? sensor->activate(connection.get(), false) : status_t(BAD_VALUE);
108618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella
108718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    }
108818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    if (err == NO_ERROR) {
108918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        SensorRegistrationInfo &reg_info =
109018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex);
109118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mActivated = false;
109218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mPackageName= connection->getPackageName();
109318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mSensorHandle = handle;
109418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        time_t rawtime = time(NULL);
109518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        struct tm * timeinfo = localtime(&rawtime);
109618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mHour = timeinfo->tm_hour;
109718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mMin = timeinfo->tm_min;
109818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mSec = timeinfo->tm_sec;
109918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        mNextSensorRegIndex = (mNextSensorRegIndex + 1) % SENSOR_REGISTRATIONS_BUF_SIZE;
11004342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
11014342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    return err;
11024342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh}
11034342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
1104ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisable(
1105ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        const sp<SensorEventConnection>& connection, int handle) {
1106fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    Mutex::Autolock _l(mLock);
1107ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    return cleanupWithoutDisableLocked(connection, handle);
1108ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian}
1109ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian
1110ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisableLocked(
1111ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        const sp<SensorEventConnection>& connection, int handle) {
1112fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    SensorRecord* rec = mActiveSensors.valueFor(handle);
1113fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (rec) {
1114fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        // see if this connection becomes inactive
1115787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian        if (connection->removeSensor(handle)) {
1116787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian            BatteryService::disableSensor(connection->getUid(), handle);
1117787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian        }
1118fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        if (connection->hasAnySensor() == false) {
11198a96955c8e14db40b16164236830fc9506a00872Aravind Akella            connection->updateLooperRegistration(mLooper);
1120fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            mActiveConnections.remove(connection);
1121fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
1122fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        // see if this sensor becomes inactive
1123fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        if (rec->removeConnection(connection)) {
1124fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            mActiveSensors.removeItem(handle);
1125f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            mActiveVirtualSensors.removeItem(handle);
1126fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            delete rec;
1127fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
11284342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        return NO_ERROR;
11297c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    }
11304342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    return BAD_VALUE;
1131fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1132fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
11337c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianstatus_t SensorService::setEventRate(const sp<SensorEventConnection>& connection,
1134b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        int handle, nsecs_t ns, const String16& opPackageName)
1135fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
113650df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian    if (mInitCheck != NO_ERROR)
113750df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian        return mInitCheck;
113850df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
1139ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian    SensorInterface* sensor = mSensorMap.valueFor(handle);
1140ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian    if (!sensor)
1141ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian        return BAD_VALUE;
1142ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian
1143b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (!canAccessSensor(sensor->getSensor(), "Tried configuring", opPackageName)) {
1144700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return BAD_VALUE;
1145700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
1146700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
11471cd700015318727d6d42236ab6274f1949fb08baMathias Agopian    if (ns < 0)
11481cd700015318727d6d42236ab6274f1949fb08baMathias Agopian        return BAD_VALUE;
11491cd700015318727d6d42236ab6274f1949fb08baMathias Agopian
115062569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian    nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
115162569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian    if (ns < minDelayNs) {
115262569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian        ns = minDelayNs;
1153ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian    }
1154ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian
1155f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    return sensor->setDelay(connection.get(), handle, ns);
1156fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1157fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1158b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslavstatus_t SensorService::flushSensor(const sp<SensorEventConnection>& connection,
1159b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        const String16& opPackageName) {
1160700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    if (mInitCheck != NO_ERROR) return mInitCheck;
11619e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    SensorDevice& dev(SensorDevice::getInstance());
11629e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    const int halVersion = dev.getHalDeviceVersion();
11639e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    status_t err(NO_ERROR);
11649e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    Mutex::Autolock _l(mLock);
11659e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    // Loop through all sensors for this connection and call flush on each of them.
11669e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    for (size_t i = 0; i < connection->mSensorInfo.size(); ++i) {
11679e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        const int handle = connection->mSensorInfo.keyAt(i);
11689e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        SensorInterface* sensor = mSensorMap.valueFor(handle);
11699e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
11709e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            ALOGE("flush called on a one-shot sensor");
11719e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            err = INVALID_OPERATION;
11729e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            continue;
11739e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        }
11748493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        if (halVersion <= SENSORS_DEVICE_API_VERSION_1_0 || isVirtualSensor(handle)) {
11759e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            // For older devices just increment pending flush count which will send a trivial
11769e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            // flush complete event.
11778a96955c8e14db40b16164236830fc9506a00872Aravind Akella            connection->incrementPendingFlushCount(handle);
11789e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        } else {
1179b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            if (!canAccessSensor(sensor->getSensor(), "Tried flushing", opPackageName)) {
1180b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                err = INVALID_OPERATION;
1181b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                continue;
1182b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            }
11839e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            status_t err_flush = sensor->flush(connection.get(), handle);
11849e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            if (err_flush == NO_ERROR) {
11859e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella                SensorRecord* rec = mActiveSensors.valueFor(handle);
11869e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella                if (rec != NULL) rec->addPendingFlushConnection(connection);
11879e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            }
11889e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            err = (err_flush != NO_ERROR) ? err_flush : err;
11899e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        }
11906c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    }
11919e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    return err;
1192700180487ffec09d9df1657b018a7caadac24b75Aravind Akella}
1193700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
1194b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslavbool SensorService::canAccessSensor(const Sensor& sensor, const char* operation,
1195b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        const String16& opPackageName) {
1196b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    const String8& requiredPermission = sensor.getRequiredPermission();
1197700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
1198b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (requiredPermission.length() <= 0) {
1199700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return true;
1200b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    }
1201b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav
1202b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    bool hasPermission = false;
1203b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav
1204b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    // Runtime permissions can't use the cache as they may change.
1205b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (sensor.isRequiredPermissionRuntime()) {
1206b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        hasPermission = checkPermission(String16(requiredPermission),
1207b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                IPCThreadState::self()->getCallingPid(), IPCThreadState::self()->getCallingUid());
1208700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    } else {
1209b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        hasPermission = PermissionCache::checkCallingPermission(String16(requiredPermission));
1210b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    }
1211b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav
1212b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (!hasPermission) {
1213b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        ALOGE("%s a sensor (%s) without holding its required permission: %s",
1214b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                operation, sensor.getName().string(), sensor.getRequiredPermission().string());
1215700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return false;
1216700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
1217b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav
1218b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    const int32_t opCode = sensor.getRequiredAppOp();
1219b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (opCode >= 0) {
1220b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        AppOpsManager appOps;
1221b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        if (appOps.noteOp(opCode, IPCThreadState::self()->getCallingUid(), opPackageName)
1222b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                        != AppOpsManager::MODE_ALLOWED) {
1223d4036b6b7f9609fe09efabdbfbb8c8f9428f76f7Andreas Gampe            ALOGE("%s a sensor (%s) without enabled required app op: %d",
1224b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                    operation, sensor.getName().string(), opCode);
1225b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            return false;
1226b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        }
1227b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    }
1228b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav
1229b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    return true;
1230700180487ffec09d9df1657b018a7caadac24b75Aravind Akella}
1231700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
12329a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockState() {
12339a844cf78f09953145200b4074d47589257a408cAravind Akella    Mutex::Autolock _l(mLock);
12349a844cf78f09953145200b4074d47589257a408cAravind Akella    checkWakeLockStateLocked();
12359a844cf78f09953145200b4074d47589257a408cAravind Akella}
12369a844cf78f09953145200b4074d47589257a408cAravind Akella
12379a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockStateLocked() {
12389a844cf78f09953145200b4074d47589257a408cAravind Akella    if (!mWakeLockAcquired) {
12399a844cf78f09953145200b4074d47589257a408cAravind Akella        return;
12409a844cf78f09953145200b4074d47589257a408cAravind Akella    }
12419a844cf78f09953145200b4074d47589257a408cAravind Akella    bool releaseLock = true;
12429a844cf78f09953145200b4074d47589257a408cAravind Akella    for (size_t i=0 ; i<mActiveConnections.size() ; i++) {
12439a844cf78f09953145200b4074d47589257a408cAravind Akella        sp<SensorEventConnection> connection(mActiveConnections[i].promote());
12449a844cf78f09953145200b4074d47589257a408cAravind Akella        if (connection != 0) {
12459a844cf78f09953145200b4074d47589257a408cAravind Akella            if (connection->needsWakeLock()) {
12469a844cf78f09953145200b4074d47589257a408cAravind Akella                releaseLock = false;
12479a844cf78f09953145200b4074d47589257a408cAravind Akella                break;
12489a844cf78f09953145200b4074d47589257a408cAravind Akella            }
12499a844cf78f09953145200b4074d47589257a408cAravind Akella        }
12509a844cf78f09953145200b4074d47589257a408cAravind Akella    }
12519a844cf78f09953145200b4074d47589257a408cAravind Akella    if (releaseLock) {
1252b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        setWakeLockAcquiredLocked(false);
1253b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    }
1254b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
1255b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
1256b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::sendEventsFromCache(const sp<SensorEventConnection>& connection) {
1257b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    Mutex::Autolock _l(mLock);
1258b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    connection->writeToSocketFromCache();
1259b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    if (connection->needsWakeLock()) {
1260b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        setWakeLockAcquiredLocked(true);
1261b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    }
1262b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
1263b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
1264b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::populateActiveConnections(
1265b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        SortedVector< sp<SensorEventConnection> >* activeConnections) {
1266b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    Mutex::Autolock _l(mLock);
1267b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    for (size_t i=0 ; i < mActiveConnections.size(); ++i) {
1268b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        sp<SensorEventConnection> connection(mActiveConnections[i].promote());
1269b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        if (connection != 0) {
1270b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            activeConnections->add(connection);
1271b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        }
12729a844cf78f09953145200b4074d47589257a408cAravind Akella    }
12739a844cf78f09953145200b4074d47589257a408cAravind Akella}
12746c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
12754949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akellabool SensorService::isWhiteListedPackage(const String8& packageName) {
1276841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    return (packageName.contains(mWhiteListedPackage.string()));
12774949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella}
12784949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
1279444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akellaint SensorService::getNumEventsForSensorType(int sensor_event_type) {
1280444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    switch (sensor_event_type) {
1281444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        case SENSOR_TYPE_ROTATION_VECTOR:
1282444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
1283444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            return 5;
1284444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella
1285444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
1286444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
1287444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            return 6;
1288444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella
1289444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        case SENSOR_TYPE_GAME_ROTATION_VECTOR:
1290444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            return 4;
1291444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella
1292444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        case SENSOR_TYPE_SIGNIFICANT_MOTION:
1293444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        case SENSOR_TYPE_STEP_DETECTOR:
1294444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        case SENSOR_TYPE_STEP_COUNTER:
1295444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            return 1;
1296444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella
1297444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella         default:
1298444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            return 3;
1299444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    }
1300444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella}
1301444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella
1302fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}; // namespace android
1303fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1304