SensorService.cpp revision 6a2d3a06caa337857cf60cfc70a9a78909ad3608
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"
36755c451c7861a029e26e5f16e319b629169e656dPeng Xu#include "SensorInterface.h"
37eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu
38984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "SensorService.h"
39eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include "SensorEventAckReceiver.h"
406a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu#include "SensorEventConnection.h"
41eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include "SensorRecord.h"
42eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include "SensorRegistrationInfo.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),
6847e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu      mWakeLockAcquired(false) {
69fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
70fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
7147e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xuvoid SensorService::onFirstRef() {
72a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block    ALOGD("nuSensorService starting...");
73f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    SensorDevice& dev(SensorDevice::getInstance());
74fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
75f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    if (dev.initCheck() == NO_ERROR) {
76f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        sensor_t const* list;
777b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian        ssize_t count = dev.getSensorList(&list);
787b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian        if (count > 0) {
797b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            ssize_t orientationIndex = -1;
80f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella            bool hasGyro = false, hasAccel = false, hasMag = false;
817b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            uint32_t virtualSensorsNeeds =
827b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    (1<<SENSOR_TYPE_GRAVITY) |
837b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    (1<<SENSOR_TYPE_LINEAR_ACCELERATION) |
84f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                    (1<<SENSOR_TYPE_ROTATION_VECTOR) |
85f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                    (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR) |
86f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                    (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR);
877b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian
887b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            for (ssize_t i=0 ; i<count ; i++) {
89f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                bool useThisSensor=true;
90f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu
917b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                switch (list[i].type) {
92f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella                    case SENSOR_TYPE_ACCELEROMETER:
93f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella                        hasAccel = true;
94f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella                        break;
95f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella                    case SENSOR_TYPE_MAGNETIC_FIELD:
96f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella                        hasMag = true;
97f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella                        break;
987b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_ORIENTATION:
997b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        orientationIndex = i;
1007b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        break;
1017b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_GYROSCOPE:
1020319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
1037b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        hasGyro = true;
1047b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        break;
1057b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_GRAVITY:
1067b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_LINEAR_ACCELERATION:
1077b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_ROTATION_VECTOR:
108f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                    case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
109f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                    case SENSOR_TYPE_GAME_ROTATION_VECTOR:
110f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                        if (IGNORE_HARDWARE_FUSION) {
111f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                            useThisSensor = false;
112f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                        } else {
113f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                            virtualSensorsNeeds &= ~(1<<list[i].type);
114f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                        }
1157b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        break;
1167b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                }
117f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                if (useThisSensor) {
118f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                    registerSensor( new HardwareSensor(list[i]) );
119f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                }
12050df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian            }
121fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1227b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            // it's safe to instantiate the SensorFusion object here
1237b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            // (it wants to be instantiated after h/w sensors have been
1247b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            // registered)
125d4036b6b7f9609fe09efabdbfbb8c8f9428f76f7Andreas Gampe            SensorFusion::getInstance();
1267b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian
127f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella            if (hasGyro && hasAccel && hasMag) {
1280319306670b0344da99efa606b6f172dde575a39Mathias Agopian                // Add Android virtual sensors if they're not already
1290319306670b0344da99efa606b6f172dde575a39Mathias Agopian                // available in the HAL
1300cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                bool needRotationVector =
1310cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                        (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) != 0;
1327b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian
1330cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                registerSensor(new RotationVectorSensor(), !needRotationVector, true);
1340cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                registerSensor(new OrientationSensor(), !needRotationVector, true);
135f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
1360cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                bool needLinearAcceleration =
1370cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                        (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) != 0;
1380319306670b0344da99efa606b6f172dde575a39Mathias Agopian
1390cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                registerSensor(new LinearAccelerationSensor(list, count),
1400cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                               !needLinearAcceleration, true);
141f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu
1420cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                // virtual debugging sensors are not for user
143755c451c7861a029e26e5f16e319b629169e656dPeng Xu                registerSensor( new CorrectedGyroSensor(list, count), true, true);
144755c451c7861a029e26e5f16e319b629169e656dPeng Xu                registerSensor( new GyroDriftSensor(), true, true);
145010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian            }
146010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian
147f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu            if (hasAccel && hasGyro) {
1480cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                bool needGravitySensor = (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) != 0;
1490cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                registerSensor(new GravitySensor(list, count), !needGravitySensor, true);
150f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu
1510cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                bool needGameRotationVector =
1520cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                        (virtualSensorsNeeds & (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR)) != 0;
1530cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                registerSensor(new GameRotationVectorSensor(), !needGameRotationVector, true);
154f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu            }
155f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu
156f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu            if (hasAccel && hasMag) {
1570cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                bool needGeoMagRotationVector =
1580cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                        (virtualSensorsNeeds & (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR)) != 0;
1590cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                registerSensor(new GeoMagRotationVectorSensor(), !needGeoMagRotationVector, true);
160f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu            }
161f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu
1625466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            // Check if the device really supports batching by looking at the FIFO event
1635466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            // counts for each sensor.
1645466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            bool batchingSupported = false;
1650cc8f809924706c7d683da30605f432635dd5bb6Peng Xu            mSensors.forEachSensor(
1660cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                    [&batchingSupported] (const Sensor& s) -> bool {
1670cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                        if (s.getFifoMaxEventCount() > 0) {
1680cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                            batchingSupported = true;
1690cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                        }
1700cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                        return !batchingSupported;
1710cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                    });
1725466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella
1735466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            if (batchingSupported) {
1745466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                // Increase socket buffer size to a max of 100 KB for batching capabilities.
1755466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                mSocketBufferSize = MAX_SOCKET_BUFFER_SIZE_BATCHED;
1765466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            } else {
1775466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                mSocketBufferSize = SOCKET_BUFFER_SIZE_NON_BATCHED;
1785466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            }
1795466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella
1805466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            // Compare the socketBufferSize value against the system limits and limit
1815466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            // it to maxSystemSocketBufferSize if necessary.
1824c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            FILE *fp = fopen("/proc/sys/net/core/wmem_max", "r");
1834c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            char line[128];
1844c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            if (fp != NULL && fgets(line, sizeof(line), fp) != NULL) {
1854c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                line[sizeof(line) - 1] = '\0';
1865466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                size_t maxSystemSocketBufferSize;
1875466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                sscanf(line, "%zu", &maxSystemSocketBufferSize);
1885466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                if (mSocketBufferSize > maxSystemSocketBufferSize) {
1895466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                    mSocketBufferSize = maxSystemSocketBufferSize;
1904c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                }
1914c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
1924c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            if (fp) {
1934c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                fclose(fp);
1944c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
1954c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
1969a844cf78f09953145200b4074d47589257a408cAravind Akella            mWakeLockAcquired = false;
19756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            mLooper = new Looper(false);
1988493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
1998493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            mSensorEventBuffer = new sensors_event_t[minBufferSize];
2008493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            mSensorEventScratch = new sensors_event_t[minBufferSize];
2018493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize];
202a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella            mCurrentOperatingMode = NORMAL;
2037830ef3dd0ff3749d974c2dd85a8fa59dc47aecaAravind Akella
20418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            mNextSensorRegIndex = 0;
20518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            for (int i = 0; i < SENSOR_REGISTRATIONS_BUF_SIZE; ++i) {
20618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                mLastNSensorRegistrations.push();
20718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            }
20818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella
20918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            mInitCheck = NO_ERROR;
210b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            mAckReceiver = new SensorEventAckReceiver(this);
211b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
2127830ef3dd0ff3749d974c2dd85a8fa59dc47aecaAravind Akella            run("SensorService", PRIORITY_URGENT_DISPLAY);
2137b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian        }
214fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
215fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
216fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
2170cc8f809924706c7d683da30605f432635dd5bb6Peng Xuconst Sensor& SensorService::registerSensor(SensorInterface* s, bool isDebug, bool isVirtual) {
2180cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    int handle = s->getSensor().getHandle();
2196a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    int type = s->getSensor().getType();
2200cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    if (mSensors.add(handle, s, isDebug, isVirtual)){
2216a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu        mRecentEvent.emplace(handle, new RecentEventLogger(type));
2220cc8f809924706c7d683da30605f432635dd5bb6Peng Xu        return s->getSensor();
2230cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    } else {
2240cc8f809924706c7d683da30605f432635dd5bb6Peng Xu        return mSensors.getNonSensor();
2250cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    }
226f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
227f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
2286a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xuconst Sensor& SensorService::registerDynamicSensorLocked(SensorInterface* s, bool isDebug) {
2290cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    return registerSensor(s, isDebug);
2302576cb63b3fe1592f54816625036566b9eb0793aPeng Xu}
2312576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
2326a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xubool SensorService::unregisterDynamicSensorLocked(int handle) {
2330cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    bool ret = mSensors.remove(handle);
2346a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
2356a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    const auto i = mRecentEvent.find(handle);
2366a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    if (i != mRecentEvent.end()) {
2376a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu        delete i->second;
2386a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu        mRecentEvent.erase(i);
2392576cb63b3fe1592f54816625036566b9eb0793aPeng Xu    }
2400cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    return ret;
241f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
242f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
2430cc8f809924706c7d683da30605f432635dd5bb6Peng Xuconst Sensor& SensorService::registerVirtualSensor(SensorInterface* s, bool isDebug) {
2440cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    return registerSensor(s, isDebug, true);
24547e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu}
24647e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu
24747e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng XuSensorService::~SensorService() {
2486a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    for (auto && entry : mRecentEvent) {
2496a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu        delete entry.second;
2506a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    }
251fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
252fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
25347e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xustatus_t SensorService::dump(int fd, const Vector<String16>& args) {
254fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    String8 result;
2551cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
256eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu        result.appendFormat("Permission Denial: can't dump SensorService from pid=%d, uid=%d\n",
257fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian                IPCThreadState::self()->getCallingPid(),
258fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian                IPCThreadState::self()->getCallingUid());
259444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    } else {
260841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella        if (args.size() > 2) {
2614949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella           return INVALID_OPERATION;
2624949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        }
2634949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        Mutex::Autolock _l(mLock);
2644949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        SensorDevice& dev(SensorDevice::getInstance());
265841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella        if (args.size() == 2 && args[0] == String16("restrict")) {
266444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            // If already in restricted mode. Ignore.
267444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            if (mCurrentOperatingMode == RESTRICTED) {
268444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                return status_t(NO_ERROR);
269444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            }
270444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            // If in any mode other than normal, ignore.
271444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            if (mCurrentOperatingMode != NORMAL) {
272444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                return INVALID_OPERATION;
273444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            }
274a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella            mCurrentOperatingMode = RESTRICTED;
2754949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            dev.disableAllSensors();
2764949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            // Clear all pending flush connections for all active sensors. If one of the active
2774949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            // connections has called flush() and the underlying sensor has been disabled before a
2784949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            // flush complete event is returned, we need to remove the connection from this queue.
2794949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            for (size_t i=0 ; i< mActiveSensors.size(); ++i) {
2804949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella                mActiveSensors.valueAt(i)->clearAllPendingFlushConnections();
2814949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            }
282841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            mWhiteListedPackage.setTo(String8(args[1]));
283444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            return status_t(NO_ERROR);
284444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        } else if (args.size() == 1 && args[0] == String16("enable")) {
285444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            // If currently in restricted mode, reset back to NORMAL mode else ignore.
286444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            if (mCurrentOperatingMode == RESTRICTED) {
287444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                mCurrentOperatingMode = NORMAL;
288444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                dev.enableAllSensors();
2896c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            }
290841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            if (mCurrentOperatingMode == DATA_INJECTION) {
291841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella               resetToNormalModeLocked();
292841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            }
293841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            mWhiteListedPackage.clear();
294444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            return status_t(NO_ERROR);
295841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella        } else if (args.size() == 2 && args[0] == String16("data_injection")) {
296841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            if (mCurrentOperatingMode == NORMAL) {
297841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                dev.disableAllSensors();
298841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                status_t err = dev.setMode(DATA_INJECTION);
299841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                if (err == NO_ERROR) {
300841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                    mCurrentOperatingMode = DATA_INJECTION;
301841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                } else {
302841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                    // Re-enable sensors.
303841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                    dev.enableAllSensors();
304841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                }
305841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                mWhiteListedPackage.setTo(String8(args[1]));
306841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                return NO_ERROR;
307841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            } else if (mCurrentOperatingMode == DATA_INJECTION) {
308841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                // Already in DATA_INJECTION mode. Treat this as a no_op.
309841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                return NO_ERROR;
310841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            } else {
311841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                // Transition to data injection mode supported only from NORMAL mode.
312841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                return INVALID_OPERATION;
313841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            }
3140cc8f809924706c7d683da30605f432635dd5bb6Peng Xu        } else if (!mSensors.hasAnySensor()) {
315ee155cadb23e84542cbf445c2aac89ae63df4cc7Aravind Akella            result.append("No Sensors on the device\n");
316444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        } else {
317444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            // Default dump the sensor list and debugging information.
3180cc8f809924706c7d683da30605f432635dd5bb6Peng Xu            //
3196a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu            result.append("Sensor Device:\n");
3206a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu            result.append(SensorDevice::getInstance().dump().c_str());
3216a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
3226a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu            result.append("Sensor List:\n");
3230cc8f809924706c7d683da30605f432635dd5bb6Peng Xu            result.append(mSensors.dump().c_str());
3246c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
3256a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu            result.append("Fusion States:\n");
326444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            SensorFusion::getInstance().dump(result);
327444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella
3280cc8f809924706c7d683da30605f432635dd5bb6Peng Xu            result.append("Recent Sensor events:\n");
3296a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu            for (auto&& i : mRecentEvent) {
3306a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                sp<SensorInterface> s = mSensors.getInterface(i.first);
3316a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                if (!i.second->isEmpty() &&
3326a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                    s->getSensor().getRequiredPermission().isEmpty()) {
3336a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                    // if there is events and sensor does not need special permission.
3346a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                    result.appendFormat("%s: ", s->getSensor().getName().string());
3356a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                    result.append(i.second->dump().c_str());
3366a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                }
3376a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu            }
3380cc8f809924706c7d683da30605f432635dd5bb6Peng Xu
339444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            result.append("Active sensors:\n");
340444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            for (size_t i=0 ; i<mActiveSensors.size() ; i++) {
341444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                int handle = mActiveSensors.keyAt(i);
342444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                result.appendFormat("%s (handle=0x%08x, connections=%zu)\n",
343444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        getSensorName(handle).string(),
344444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        handle,
345444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        mActiveSensors.valueAt(i)->getNumConnections());
346ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            }
3474c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
348d4036b6b7f9609fe09efabdbfbb8c8f9428f76f7Andreas Gampe            result.appendFormat("Socket Buffer size = %zd events\n",
349444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                                mSocketBufferSize/sizeof(sensors_event_t));
35018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            result.appendFormat("WakeLock Status: %s \n", mWakeLockAcquired ? "acquired" :
35118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                    "not held");
352444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            result.appendFormat("Mode :");
353444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            switch(mCurrentOperatingMode) {
354444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella               case NORMAL:
355444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                   result.appendFormat(" NORMAL\n");
356444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                   break;
357444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella               case RESTRICTED:
358841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                   result.appendFormat(" RESTRICTED : %s\n", mWhiteListedPackage.string());
359444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                   break;
360444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella               case DATA_INJECTION:
361841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                   result.appendFormat(" DATA_INJECTION : %s\n", mWhiteListedPackage.string());
362444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            }
363444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            result.appendFormat("%zd active connections\n", mActiveConnections.size());
3644c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
365444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            for (size_t i=0 ; i < mActiveConnections.size() ; i++) {
366444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                sp<SensorEventConnection> connection(mActiveConnections[i].promote());
367444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                if (connection != 0) {
368444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.appendFormat("Connection Number: %zu \n", i);
369444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    connection->dump(result);
370444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                }
3714c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
37218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella
37318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            result.appendFormat("Previous Registrations:\n");
37418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            // Log in the reverse chronological order.
37518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            int currentIndex = (mNextSensorRegIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) %
37618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                SENSOR_REGISTRATIONS_BUF_SIZE;
37718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            const int startIndex = currentIndex;
37818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            do {
37918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                const SensorRegistrationInfo& reg_info = mLastNSensorRegistrations[currentIndex];
38018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                if (SensorRegistrationInfo::isSentinel(reg_info)) {
38118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                    // Ignore sentinel, proceed to next item.
38218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                    currentIndex = (currentIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) %
38318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                        SENSOR_REGISTRATIONS_BUF_SIZE;
38418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                    continue;
38518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                }
38618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                if (reg_info.mActivated) {
38718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                   result.appendFormat("%02d:%02d:%02d activated package=%s handle=0x%08x "
38818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                           "samplingRate=%dus maxReportLatency=%dus\n",
38918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                           reg_info.mHour, reg_info.mMin, reg_info.mSec,
39018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                           reg_info.mPackageName.string(), reg_info.mSensorHandle,
39118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                           reg_info.mSamplingRateUs, reg_info.mMaxReportLatencyUs);
39218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                } else {
39318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                   result.appendFormat("%02d:%02d:%02d de-activated package=%s handle=0x%08x\n",
39418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                           reg_info.mHour, reg_info.mMin, reg_info.mSec,
39518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                           reg_info.mPackageName.string(), reg_info.mSensorHandle);
39618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                }
39718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                currentIndex = (currentIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) %
39818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                        SENSOR_REGISTRATIONS_BUF_SIZE;
39918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            } while(startIndex != currentIndex);
4004c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
401fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
402fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    write(fd, result.string(), result.size());
403fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return NO_ERROR;
404fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
405fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
4060cc8f809924706c7d683da30605f432635dd5bb6Peng Xu//TODO: move to SensorEventConnection later
4079a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::cleanupAutoDisabledSensorLocked(const sp<SensorEventConnection>& connection,
4084342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        sensors_event_t const* buffer, const int count) {
4094342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    for (int i=0 ; i<count ; i++) {
4104342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        int handle = buffer[i].sensor;
4118493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        if (buffer[i].type == SENSOR_TYPE_META_DATA) {
4128493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            handle = buffer[i].meta_data.sensor;
4138493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        }
4140e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella        if (connection->hasSensor(handle)) {
415755c451c7861a029e26e5f16e319b629169e656dPeng Xu            sp<SensorInterface> si = getSensorInterfaceFromHandle(handle);
4160e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            // If this buffer has an event from a one_shot sensor and this connection is registered
4170e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            // for this particular one_shot sensor, try cleaning up the connection.
418755c451c7861a029e26e5f16e319b629169e656dPeng Xu            if (si != nullptr &&
4190cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                si->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
4200cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                si->autoDisable(connection.get(), handle);
4219a844cf78f09953145200b4074d47589257a408cAravind Akella                cleanupWithoutDisableLocked(connection, handle);
4224342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            }
423a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
4244342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
425a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella   }
4264342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh}
4274342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
42847e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xubool SensorService::threadLoop() {
429a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block    ALOGD("nuSensorService thread starting...");
430fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
431eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu    // each virtual sensor could generate an event per "real" event, that's why we need to size
432eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu    // numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT.  in practice, this is too
433eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu    // aggressive, but guaranteed to be enough.
4340cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    const size_t vcount = mSensors.getVirtualSensors().size();
43590ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
4360cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    const size_t numEventMax = minBufferSize / (1 + vcount);
43790ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian
438f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    SensorDevice& device(SensorDevice::getInstance());
439fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
4404342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    const int halVersion = device.getHalDeviceVersion();
441fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    do {
4428493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
4438493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        if (count < 0) {
444f5a1230d322c14c42331d0a1536b50c87742973bSteve Block            ALOGE("sensor poll failed (%s)", strerror(-count));
445fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            break;
446fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
44756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
44856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        // Reset sensors_event_t.flags to zero for all events in the buffer.
44956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        for (int i = 0; i < count; i++) {
4508493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella             mSensorEventBuffer[i].flags = 0;
45156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        }
452e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella
453eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu        // Make a copy of the connection vector as some connections may be removed during the course
454eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu        // of this loop (especially when one-shot sensor events are present in the sensor_event
455eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu        // buffer). Promote all connections to StrongPointers before the lock is acquired. If the
456eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu        // destructor of the sp gets called when the lock is acquired, it may result in a deadlock
457eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu        // as ~SensorEventConnection() needs to acquire mLock again for cleanup. So copy all the
458eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu        // strongPointers to a vector before the lock is acquired.
459e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella        SortedVector< sp<SensorEventConnection> > activeConnections;
460b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        populateActiveConnections(&activeConnections);
461eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu
4629a844cf78f09953145200b4074d47589257a408cAravind Akella        Mutex::Autolock _l(mLock);
4639a844cf78f09953145200b4074d47589257a408cAravind Akella        // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The
4649a844cf78f09953145200b4074d47589257a408cAravind Akella        // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock,
4659a844cf78f09953145200b4074d47589257a408cAravind Akella        // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should
4669a844cf78f09953145200b4074d47589257a408cAravind Akella        // not be interleaved with decrementing SensorEventConnection::mWakeLockRefCount and
4679a844cf78f09953145200b4074d47589257a408cAravind Akella        // releasing the wakelock.
4689a844cf78f09953145200b4074d47589257a408cAravind Akella        bool bufferHasWakeUpEvent = false;
4694342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        for (int i = 0; i < count; i++) {
4708493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            if (isWakeUpSensorEvent(mSensorEventBuffer[i])) {
4719a844cf78f09953145200b4074d47589257a408cAravind Akella                bufferHasWakeUpEvent = true;
4729a844cf78f09953145200b4074d47589257a408cAravind Akella                break;
4734342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            }
4744342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
4754342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
4769a844cf78f09953145200b4074d47589257a408cAravind Akella        if (bufferHasWakeUpEvent && !mWakeLockAcquired) {
477b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            setWakeLockAcquiredLocked(true);
4789a844cf78f09953145200b4074d47589257a408cAravind Akella        }
4798493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        recordLastValueLocked(mSensorEventBuffer, count);
48094e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian
481f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        // handle virtual sensors
482f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        if (count && vcount) {
4838493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            sensors_event_t const * const event = mSensorEventBuffer;
484755c451c7861a029e26e5f16e319b629169e656dPeng Xu            if (!mActiveVirtualSensors.empty()) {
485f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                size_t k = 0;
486984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                SensorFusion& fusion(SensorFusion::getInstance());
487984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                if (fusion.isEnabled()) {
488984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                    for (size_t i=0 ; i<size_t(count) ; i++) {
489984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                        fusion.process(event[i]);
490984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                    }
491984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                }
492d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) {
493755c451c7861a029e26e5f16e319b629169e656dPeng Xu                    for (int handle : mActiveVirtualSensors) {
494d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                        if (count + k >= minBufferSize) {
495d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                            ALOGE("buffer too small to hold all events: "
496db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn                                    "count=%zd, k=%zu, size=%zu",
497d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                                    count, k, minBufferSize);
498d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                            break;
499d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                        }
500f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                        sensors_event_t out;
501755c451c7861a029e26e5f16e319b629169e656dPeng Xu                        sp<SensorInterface> si = mSensors.getInterface(handle);
502755c451c7861a029e26e5f16e319b629169e656dPeng Xu                        if (si == nullptr) {
503755c451c7861a029e26e5f16e319b629169e656dPeng Xu                            ALOGE("handle %d is not an valid virtual sensor", handle);
504755c451c7861a029e26e5f16e319b629169e656dPeng Xu                            continue;
505755c451c7861a029e26e5f16e319b629169e656dPeng Xu                        }
506755c451c7861a029e26e5f16e319b629169e656dPeng Xu
507d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                        if (si->process(&out, event[i])) {
5088493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                            mSensorEventBuffer[count + k] = out;
509f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                            k++;
510f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                        }
511f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    }
512f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                }
513f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                if (k) {
514f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    // record the last synthesized values
5158493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    recordLastValueLocked(&mSensorEventBuffer[count], k);
516f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    count += k;
517f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    // sort the buffer by time-stamps
5188493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    sortEventBuffer(mSensorEventBuffer, count);
519f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                }
520f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            }
521f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        }
522f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
5234342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // handle backward compatibility for RotationVector sensor
5244342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) {
5254342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            for (int i = 0; i < count; i++) {
5268493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                if (mSensorEventBuffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) {
5274342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                    // All the 4 components of the quaternion should be available
5284342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                    // No heading accuracy. Set it to -1
5298493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    mSensorEventBuffer[i].data[4] = -1;
5308493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                }
5318493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            }
5328493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        }
5338493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella
5348493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        for (int i = 0; i < count; ++i) {
5350cc8f809924706c7d683da30605f432635dd5bb6Peng Xu            // Map flush_complete_events in the buffer to SensorEventConnections which called flush
5360cc8f809924706c7d683da30605f432635dd5bb6Peng Xu            // on the hardware sensor. mapFlushEventsToConnections[i] will be the
5370cc8f809924706c7d683da30605f432635dd5bb6Peng Xu            // SensorEventConnection mapped to the corresponding flush_complete_event in
5380cc8f809924706c7d683da30605f432635dd5bb6Peng Xu            // mSensorEventBuffer[i] if such a mapping exists (NULL otherwise).
5398493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            mMapFlushEventsToConnections[i] = NULL;
5408493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            if (mSensorEventBuffer[i].type == SENSOR_TYPE_META_DATA) {
5418493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                const int sensor_handle = mSensorEventBuffer[i].meta_data.sensor;
5428493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                SensorRecord* rec = mActiveSensors.valueFor(sensor_handle);
5438493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                if (rec != NULL) {
5448493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    mMapFlushEventsToConnections[i] = rec->getFirstPendingFlushConnection();
5458493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    rec->removeFirstPendingFlushConnection();
5464342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                }
5474342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            }
5482576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
5492576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            // handle dynamic sensor meta events, process registration and unregistration of dynamic
5502576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            // sensor based on content of event.
5512576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            if (mSensorEventBuffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META) {
5522576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                if (mSensorEventBuffer[i].dynamic_sensor_meta.connected) {
5532576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    int handle = mSensorEventBuffer[i].dynamic_sensor_meta.handle;
5542576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    const sensor_t& dynamicSensor =
5552576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                            *(mSensorEventBuffer[i].dynamic_sensor_meta.sensor);
5562576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    ALOGI("Dynamic sensor handle 0x%x connected, type %d, name %s",
5572576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                          handle, dynamicSensor.type, dynamicSensor.name);
5582576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
5590cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                    if (mSensors.isNewHandle(handle)) {
5606a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                        const auto& uuid = mSensorEventBuffer[i].dynamic_sensor_meta.uuid;
56147e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu                        sensor_t s = dynamicSensor;
56247e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu                        // make sure the dynamic sensor flag is set
56347e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu                        s.flags |= DYNAMIC_SENSOR_MASK;
56447e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu                        // force the handle to be consistent
56547e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu                        s.handle = handle;
5666a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
5676a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                        SensorInterface *si = new HardwareSensor(s, uuid);
56847e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu
5690cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                        // This will release hold on dynamic sensor meta, so it should be called
5700cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                        // after Sensor object is created.
57147e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu                        device.handleDynamicSensorConnection(handle, true /*connected*/);
5726a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                        registerDynamicSensorLocked(si);
57347e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu                    } else {
57447e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu                        ALOGE("Handle %d has been used, cannot use again before reboot.", handle);
57547e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu                    }
5762576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                } else {
5772576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    int handle = mSensorEventBuffer[i].dynamic_sensor_meta.handle;
5782576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    ALOGI("Dynamic sensor handle 0x%x disconnected", handle);
5792576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
5802576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    device.handleDynamicSensorConnection(handle, false /*connected*/);
5816a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                    if (!unregisterDynamicSensorLocked(handle)) {
5822576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                        ALOGE("Dynamic sensor release error.");
5832576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    }
5842576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
5852576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    size_t numConnections = activeConnections.size();
5862576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    for (size_t i=0 ; i < numConnections; ++i) {
5872576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                        if (activeConnections[i] != NULL) {
5882576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                            activeConnections[i]->removeSensor(handle);
5892576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                        }
5902576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    }
5912576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                }
5922576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            }
5934342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
5944342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
5952576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
5969a844cf78f09953145200b4074d47589257a408cAravind Akella        // Send our events to clients. Check the state of wake lock for each client and release the
5979a844cf78f09953145200b4074d47589257a408cAravind Akella        // lock if none of the clients need it.
5989a844cf78f09953145200b4074d47589257a408cAravind Akella        bool needsWakeLock = false;
5998493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        size_t numConnections = activeConnections.size();
6008493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        for (size_t i=0 ; i < numConnections; ++i) {
601e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella            if (activeConnections[i] != 0) {
602e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella                activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,
6038493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                        mMapFlushEventsToConnections);
604e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella                needsWakeLock |= activeConnections[i]->needsWakeLock();
6058493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                // If the connection has one-shot sensors, it may be cleaned up after first trigger.
6068493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                // Early check for one-shot sensors.
607e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella                if (activeConnections[i]->hasOneShotSensors()) {
608e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella                    cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer,
609e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella                            count);
6108493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                }
611fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            }
612fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
6134342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
6149a844cf78f09953145200b4074d47589257a408cAravind Akella        if (mWakeLockAcquired && !needsWakeLock) {
615b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            setWakeLockAcquiredLocked(false);
6169a844cf78f09953145200b4074d47589257a408cAravind Akella        }
6178493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella    } while (!Thread::exitPending());
618fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
6193c20fbed7f3a916ced10f2ed5a272271b7d81edeSteve Block    ALOGW("Exiting SensorService::threadLoop => aborting...");
6201a62301fc58cd2af18239b0415813461bf5fc41bMathias Agopian    abort();
621fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return false;
622fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
623fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
62456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellasp<Looper> SensorService::getLooper() const {
62556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    return mLooper;
62656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella}
62756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
628b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::resetAllWakeLockRefCounts() {
629b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    SortedVector< sp<SensorEventConnection> > activeConnections;
630b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    populateActiveConnections(&activeConnections);
631b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    {
632b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        Mutex::Autolock _l(mLock);
633b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        for (size_t i=0 ; i < activeConnections.size(); ++i) {
634b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            if (activeConnections[i] != 0) {
635b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella                activeConnections[i]->resetWakeLockRefCount();
636b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            }
637b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        }
638b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        setWakeLockAcquiredLocked(false);
639b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    }
640b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
641b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
642b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::setWakeLockAcquiredLocked(bool acquire) {
643b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    if (acquire) {
644b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        if (!mWakeLockAcquired) {
645b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
646b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            mWakeLockAcquired = true;
647b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        }
648b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        mLooper->wake();
649b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    } else {
650b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        if (mWakeLockAcquired) {
651b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            release_wake_lock(WAKE_LOCK_NAME);
652b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            mWakeLockAcquired = false;
653b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        }
654b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    }
655b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
656b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
657b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellabool SensorService::isWakeLockAcquired() {
658b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    Mutex::Autolock _l(mLock);
659b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    return mWakeLockAcquired;
660b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
661b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
66256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellabool SensorService::SensorEventAckReceiver::threadLoop() {
66356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    ALOGD("new thread SensorEventAckReceiver");
664b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    sp<Looper> looper = mService->getLooper();
66556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    do {
666b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        bool wakeLockAcquired = mService->isWakeLockAcquired();
667b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        int timeout = -1;
668b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        if (wakeLockAcquired) timeout = 5000;
669b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        int ret = looper->pollOnce(timeout);
670b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        if (ret == ALOOPER_POLL_TIMEOUT) {
671b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella           mService->resetAllWakeLockRefCounts();
672b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        }
67356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    } while(!Thread::exitPending());
67456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    return false;
67556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella}
67656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
6779a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::recordLastValueLocked(
6784b84704b97300eff3ebfab85652e64d54149d205Aravind Akella        const sensors_event_t* buffer, size_t count) {
6794b84704b97300eff3ebfab85652e64d54149d205Aravind Akella    for (size_t i = 0; i < count; i++) {
6802576cb63b3fe1592f54816625036566b9eb0793aPeng Xu        if (buffer[i].type == SENSOR_TYPE_META_DATA ||
6812576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            buffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META ||
6826a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu            buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO) {
6832576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            continue;
6842576cb63b3fe1592f54816625036566b9eb0793aPeng Xu        }
6852576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
6866a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu        auto logger = mRecentEvent.find(buffer[i].sensor);
6876a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu        if (logger != mRecentEvent.end()) {
6886a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu            logger->second->addEvent(buffer[i]);
68994e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian        }
69094e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian    }
69194e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian}
69294e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian
69347e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xuvoid SensorService::sortEventBuffer(sensors_event_t* buffer, size_t count) {
694f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    struct compar {
695f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        static int cmp(void const* lhs, void const* rhs) {
696f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            sensors_event_t const* l = static_cast<sensors_event_t const*>(lhs);
697f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            sensors_event_t const* r = static_cast<sensors_event_t const*>(rhs);
698a5c106a4f0afcf061728a1cb7c8c3b908728575dMathias Agopian            return l->timestamp - r->timestamp;
699f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        }
700f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    };
701f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    qsort(buffer, count, sizeof(sensors_event_t), compar::cmp);
702f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
703f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
7045d2707214dfb97bd8dfcc6620be36841d3c82420Mathias AgopianString8 SensorService::getSensorName(int handle) const {
7050cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    return mSensors.getName(handle);
7065d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian}
7075d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian
708b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akellabool SensorService::isVirtualSensor(int handle) const {
709755c451c7861a029e26e5f16e319b629169e656dPeng Xu    sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
710755c451c7861a029e26e5f16e319b629169e656dPeng Xu    return sensor != nullptr && sensor->isVirtual();
711b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella}
712b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella
7139a844cf78f09953145200b4074d47589257a408cAravind Akellabool SensorService::isWakeUpSensorEvent(const sensors_event_t& event) const {
7147869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan    int handle = event.sensor;
7157869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan    if (event.type == SENSOR_TYPE_META_DATA) {
7167869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan        handle = event.meta_data.sensor;
7177869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan    }
718755c451c7861a029e26e5f16e319b629169e656dPeng Xu    sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
719755c451c7861a029e26e5f16e319b629169e656dPeng Xu    return sensor != nullptr && sensor->getSensor().isWakeUpSensor();
7209a844cf78f09953145200b4074d47589257a408cAravind Akella}
7219a844cf78f09953145200b4074d47589257a408cAravind Akella
72247e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng XuVector<Sensor> SensorService::getSensorList(const String16& opPackageName) {
72333264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian    char value[PROPERTY_VALUE_MAX];
72433264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian    property_get("debug.sensors", value, "0");
725700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    const Vector<Sensor>& initialSensorList = (atoi(value)) ?
7260cc8f809924706c7d683da30605f432635dd5bb6Peng Xu            mSensors.getUserDebugSensors() : mSensors.getUserSensors();
727700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    Vector<Sensor> accessibleSensorList;
728700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    for (size_t i = 0; i < initialSensorList.size(); i++) {
729700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        Sensor sensor = initialSensorList[i];
730b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        if (canAccessSensor(sensor, "getSensorList", opPackageName)) {
731700180487ffec09d9df1657b018a7caadac24b75Aravind Akella            accessibleSensorList.add(sensor);
732700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        } else {
733b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            ALOGI("Skipped sensor %s because it requires permission %s and app op %d",
7345f6199373dc1e07d2ee5edbae7ecfa08a065492eBernhard Rosenkränzer                  sensor.getName().string(),
735b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                  sensor.getRequiredPermission().string(),
736b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                  sensor.getRequiredAppOp());
737700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        }
73833264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian    }
739700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    return accessibleSensorList;
740fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
741fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
74247e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng XuVector<Sensor> SensorService::getDynamicSensorList(const String16& opPackageName) {
7432576cb63b3fe1592f54816625036566b9eb0793aPeng Xu    Vector<Sensor> accessibleSensorList;
7440cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    mSensors.forEachSensor(
7450cc8f809924706c7d683da30605f432635dd5bb6Peng Xu            [&opPackageName, &accessibleSensorList] (const Sensor& sensor) -> bool {
746755c451c7861a029e26e5f16e319b629169e656dPeng Xu                if (sensor.isDynamicSensor()) {
747755c451c7861a029e26e5f16e319b629169e656dPeng Xu                    if (canAccessSensor(sensor, "getDynamicSensorList", opPackageName)) {
748755c451c7861a029e26e5f16e319b629169e656dPeng Xu                        accessibleSensorList.add(sensor);
749755c451c7861a029e26e5f16e319b629169e656dPeng Xu                    } else {
750755c451c7861a029e26e5f16e319b629169e656dPeng Xu                        ALOGI("Skipped sensor %s because it requires permission %s and app op %" PRId32,
751755c451c7861a029e26e5f16e319b629169e656dPeng Xu                              sensor.getName().string(),
752755c451c7861a029e26e5f16e319b629169e656dPeng Xu                              sensor.getRequiredPermission().string(),
753755c451c7861a029e26e5f16e319b629169e656dPeng Xu                              sensor.getRequiredAppOp());
754755c451c7861a029e26e5f16e319b629169e656dPeng Xu                    }
7550cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                }
7560cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                return true;
7570cc8f809924706c7d683da30605f432635dd5bb6Peng Xu            });
7582576cb63b3fe1592f54816625036566b9eb0793aPeng Xu    return accessibleSensorList;
7592576cb63b3fe1592f54816625036566b9eb0793aPeng Xu}
7602576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
761a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellasp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName,
762b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        int requestedMode, const String16& opPackageName) {
763a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    // Only 2 modes supported for a SensorEventConnection ... NORMAL and DATA_INJECTION.
764a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    if (requestedMode != NORMAL && requestedMode != DATA_INJECTION) {
765a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        return NULL;
766a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    }
767a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
768a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    Mutex::Autolock _l(mLock);
769841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    // To create a client in DATA_INJECTION mode to inject data, SensorService should already be
770841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    // operating in DI mode.
771841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    if (requestedMode == DATA_INJECTION) {
772841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella        if (mCurrentOperatingMode != DATA_INJECTION) return NULL;
773841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella        if (!isWhiteListedPackage(packageName)) return NULL;
774841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    }
775841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella
7765307d17fe33fc26eeeacd6339a9fbfe96cf56873Mathias Agopian    uid_t uid = IPCThreadState::self()->getCallingUid();
777a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    sp<SensorEventConnection> result(new SensorEventConnection(this, uid, packageName,
778b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            requestedMode == DATA_INJECTION, opPackageName));
779a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    if (requestedMode == DATA_INJECTION) {
780a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        if (mActiveConnections.indexOf(result) < 0) {
781a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella            mActiveConnections.add(result);
782a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        }
783a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        // Add the associated file descriptor to the Looper for polling whenever there is data to
784a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        // be injected.
785a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        result->updateLooperRegistration(mLooper);
786a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    }
787fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return result;
788fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
789fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
790841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akellaint SensorService::isDataInjectionEnabled() {
791a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    Mutex::Autolock _l(mLock);
792841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    return (mCurrentOperatingMode == DATA_INJECTION);
793a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella}
794a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
795a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatus_t SensorService::resetToNormalMode() {
796a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    Mutex::Autolock _l(mLock);
797a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    return resetToNormalModeLocked();
798a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella}
799a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
800a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatus_t SensorService::resetToNormalModeLocked() {
801a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    SensorDevice& dev(SensorDevice::getInstance());
802a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    dev.enableAllSensors();
803a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    status_t err = dev.setMode(NORMAL);
804a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    mCurrentOperatingMode = NORMAL;
805a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    return err;
806a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella}
807a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
80847e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xuvoid SensorService::cleanupConnection(SensorEventConnection* c) {
809fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    Mutex::Autolock _l(mLock);
810db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian    const wp<SensorEventConnection> connection(c);
8117c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    size_t size = mActiveSensors.size();
812db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn    ALOGD_IF(DEBUG_CONNECTIONS, "%zu active sensors", size);
8137c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    for (size_t i=0 ; i<size ; ) {
814db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        int handle = mActiveSensors.keyAt(i);
815db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        if (c->hasSensor(handle)) {
816db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn            ALOGD_IF(DEBUG_CONNECTIONS, "%zu: disabling handle=0x%08x", i, handle);
817755c451c7861a029e26e5f16e319b629169e656dPeng Xu            sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
818755c451c7861a029e26e5f16e319b629169e656dPeng Xu            if (sensor != nullptr) {
819db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian                sensor->activate(c, false);
820755c451c7861a029e26e5f16e319b629169e656dPeng Xu            } else {
821755c451c7861a029e26e5f16e319b629169e656dPeng Xu                ALOGE("sensor interface of handle=0x%08x is null!", handle);
822f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            }
8238a96955c8e14db40b16164236830fc9506a00872Aravind Akella            c->removeSensor(handle);
824db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        }
825db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        SensorRecord* rec = mActiveSensors.valueAt(i);
826db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn        ALOGE_IF(!rec, "mActiveSensors[%zu] is null (handle=0x%08x)!", i, handle);
827a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block        ALOGD_IF(DEBUG_CONNECTIONS,
828db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn                "removing connection %p for sensor[%zu].handle=0x%08x",
829a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian                c, i, handle);
830a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian
831db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        if (rec && rec->removeConnection(connection)) {
832a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block            ALOGD_IF(DEBUG_CONNECTIONS, "... and it was the last connection");
8337c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            mActiveSensors.removeItemsAt(i, 1);
834755c451c7861a029e26e5f16e319b629169e656dPeng Xu            mActiveVirtualSensors.erase(handle);
8357c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            delete rec;
8367c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            size--;
8377c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian        } else {
8387c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            i++;
839fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
840fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
8418a96955c8e14db40b16164236830fc9506a00872Aravind Akella    c->updateLooperRegistration(mLooper);
8427c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    mActiveConnections.remove(connection);
843787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian    BatteryService::cleanup(c->getUid());
8449a844cf78f09953145200b4074d47589257a408cAravind Akella    if (c->needsWakeLock()) {
8459a844cf78f09953145200b4074d47589257a408cAravind Akella        checkWakeLockStateLocked();
8469a844cf78f09953145200b4074d47589257a408cAravind Akella    }
847fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
848fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
849755c451c7861a029e26e5f16e319b629169e656dPeng Xusp<SensorInterface> SensorService::getSensorInterfaceFromHandle(int handle) const {
8500cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    return mSensors.getInterface(handle);
85147e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu}
85247e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu
853700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
854fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::enable(const sp<SensorEventConnection>& connection,
855b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags,
85647e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu        const String16& opPackageName) {
85750df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian    if (mInitCheck != NO_ERROR)
85850df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian        return mInitCheck;
85950df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
860755c451c7861a029e26e5f16e319b629169e656dPeng Xu    sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
861755c451c7861a029e26e5f16e319b629169e656dPeng Xu    if (sensor == nullptr ||
862755c451c7861a029e26e5f16e319b629169e656dPeng Xu        !canAccessSensor(sensor->getSensor(), "Tried enabling", opPackageName)) {
863700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return BAD_VALUE;
864700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
865700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
866ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    Mutex::Autolock _l(mLock);
867841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    if ((mCurrentOperatingMode == RESTRICTED || mCurrentOperatingMode == DATA_INJECTION)
868841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella           && !isWhiteListedPackage(connection->getPackageName())) {
8694949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        return INVALID_OPERATION;
8704949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    }
8714949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
8724342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    SensorRecord* rec = mActiveSensors.valueFor(handle);
8734342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (rec == 0) {
8744342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        rec = new SensorRecord(connection);
8754342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        mActiveSensors.add(handle, rec);
8764342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (sensor->isVirtual()) {
877755c451c7861a029e26e5f16e319b629169e656dPeng Xu            mActiveVirtualSensors.emplace(handle);
8783560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        }
8794342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    } else {
8804342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (rec->addConnection(connection)) {
8819a844cf78f09953145200b4074d47589257a408cAravind Akella            // this sensor is already activated, but we are adding a connection that uses it.
8829a844cf78f09953145200b4074d47589257a408cAravind Akella            // Immediately send down the last known value of the requested sensor if it's not a
8834342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            // "continuous" sensor.
8840e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ON_CHANGE) {
8859a844cf78f09953145200b4074d47589257a408cAravind Akella                // NOTE: The wake_up flag of this event may get set to
8869a844cf78f09953145200b4074d47589257a408cAravind Akella                // WAKE_UP_SENSOR_EVENT_NEEDS_ACK if this is a wake_up event.
8876a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
8886a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                auto logger = mRecentEvent.find(handle);
8896a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                if (logger != mRecentEvent.end()) {
890444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    sensors_event_t event;
891444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    // It is unlikely that this buffer is empty as the sensor is already active.
892444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    // One possible corner case may be two applications activating an on-change
893444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    // sensor at the same time.
8946a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                    if(logger->second->populateLastEvent(&event)) {
895444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        event.sensor = handle;
896444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        if (event.version == sizeof(sensors_event_t)) {
897444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                            if (isWakeUpSensorEvent(event) && !mWakeLockAcquired) {
898444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                                setWakeLockAcquiredLocked(true);
899444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                            }
900444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                            connection->sendEvents(&event, 1, NULL);
901444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                            if (!connection->needsWakeLock() && mWakeLockAcquired) {
902444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                                checkWakeLockStateLocked();
903444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                            }
904444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        }
9059a844cf78f09953145200b4074d47589257a408cAravind Akella                    }
906f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                }
9077c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            }
908fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
909fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
9104342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
9114342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (connection->addSensor(handle)) {
9124342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        BatteryService::enableSensor(connection->getUid(), handle);
9134342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // the sensor was added (which means it wasn't already there)
9144342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // so, see if this connection becomes active
9154342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (mActiveConnections.indexOf(connection) < 0) {
9164342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            mActiveConnections.add(connection);
9174342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
9184342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    } else {
9194342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        ALOGW("sensor %08x already enabled in connection %p (ignoring)",
9204342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            handle, connection.get());
9214342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
9224342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
923724d91d778e71c8186399f4955de14b54812b3edAravind Akella    nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
924724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (samplingPeriodNs < minDelayNs) {
925724d91d778e71c8186399f4955de14b54812b3edAravind Akella        samplingPeriodNs = minDelayNs;
926724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
927724d91d778e71c8186399f4955de14b54812b3edAravind Akella
9286c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d"
9296c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                                "rate=%" PRId64 " timeout== %" PRId64"",
930724d91d778e71c8186399f4955de14b54812b3edAravind Akella             handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs);
931724d91d778e71c8186399f4955de14b54812b3edAravind Akella
9324949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    status_t err = sensor->batch(connection.get(), handle, 0, samplingPeriodNs,
933724d91d778e71c8186399f4955de14b54812b3edAravind Akella                                 maxBatchReportLatencyNs);
9346c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
93520483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu    // Call flush() before calling activate() on the sensor. Wait for a first
93620483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu    // flush complete event before sending events on this connection. Ignore
93720483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu    // one-shot sensors which don't support flush(). Ignore on-change sensors
93820483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu    // to maintain the on-change logic (any on-change events except the initial
93920483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu    // one should be trigger by a change in value). Also if this sensor isn't
94020483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu    // already active, don't call flush().
94120483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu    if (err == NO_ERROR &&
9422576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            sensor->getSensor().getReportingMode() == AREPORTING_MODE_CONTINUOUS &&
9435466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            rec->getNumConnections() > 1) {
9445466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella        connection->setFirstFlushPending(handle, true);
9454c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        status_t err_flush = sensor->flush(connection.get(), handle);
9465466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella        // Flush may return error if the underlying h/w sensor uses an older HAL.
9476c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        if (err_flush == NO_ERROR) {
9486c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            rec->addPendingFlushConnection(connection.get());
9495466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella        } else {
9505466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            connection->setFirstFlushPending(handle, false);
9514c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
9524c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
953724d91d778e71c8186399f4955de14b54812b3edAravind Akella
954724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (err == NO_ERROR) {
955724d91d778e71c8186399f4955de14b54812b3edAravind Akella        ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle);
956724d91d778e71c8186399f4955de14b54812b3edAravind Akella        err = sensor->activate(connection.get(), true);
957724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
958724d91d778e71c8186399f4955de14b54812b3edAravind Akella
9598a96955c8e14db40b16164236830fc9506a00872Aravind Akella    if (err == NO_ERROR) {
9608a96955c8e14db40b16164236830fc9506a00872Aravind Akella        connection->updateLooperRegistration(mLooper);
96118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        SensorRegistrationInfo &reg_info =
96218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex);
96318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mSensorHandle = handle;
96418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mSamplingRateUs = samplingPeriodNs/1000;
96518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mMaxReportLatencyUs = maxBatchReportLatencyNs/1000;
96618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mActivated = true;
96718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mPackageName = connection->getPackageName();
96818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        time_t rawtime = time(NULL);
96918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        struct tm * timeinfo = localtime(&rawtime);
97018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mHour = timeinfo->tm_hour;
97118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mMin = timeinfo->tm_min;
97218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mSec = timeinfo->tm_sec;
97318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        mNextSensorRegIndex = (mNextSensorRegIndex + 1) % SENSOR_REGISTRATIONS_BUF_SIZE;
97456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    }
97556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
9764342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (err != NO_ERROR) {
977724d91d778e71c8186399f4955de14b54812b3edAravind Akella        // batch/activate has failed, reset our state.
978ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        cleanupWithoutDisableLocked(connection, handle);
9794342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
980fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return err;
981fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
982fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
98347e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xustatus_t SensorService::disable(const sp<SensorEventConnection>& connection, int handle) {
98450df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian    if (mInitCheck != NO_ERROR)
98550df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian        return mInitCheck;
98650df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
987ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    Mutex::Autolock _l(mLock);
988ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    status_t err = cleanupWithoutDisableLocked(connection, handle);
9894342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (err == NO_ERROR) {
990755c451c7861a029e26e5f16e319b629169e656dPeng Xu        sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
991755c451c7861a029e26e5f16e319b629169e656dPeng Xu        err = sensor != nullptr ? sensor->activate(connection.get(), false) : status_t(BAD_VALUE);
99218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella
99318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    }
99418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    if (err == NO_ERROR) {
99518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        SensorRegistrationInfo &reg_info =
99618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex);
99718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mActivated = false;
99818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mPackageName= connection->getPackageName();
99918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mSensorHandle = handle;
100018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        time_t rawtime = time(NULL);
100118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        struct tm * timeinfo = localtime(&rawtime);
100218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mHour = timeinfo->tm_hour;
100318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mMin = timeinfo->tm_min;
100418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mSec = timeinfo->tm_sec;
100518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        mNextSensorRegIndex = (mNextSensorRegIndex + 1) % SENSOR_REGISTRATIONS_BUF_SIZE;
10064342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
10074342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    return err;
10084342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh}
10094342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
1010ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisable(
1011ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        const sp<SensorEventConnection>& connection, int handle) {
1012fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    Mutex::Autolock _l(mLock);
1013ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    return cleanupWithoutDisableLocked(connection, handle);
1014ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian}
1015ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian
1016ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisableLocked(
1017ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        const sp<SensorEventConnection>& connection, int handle) {
1018fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    SensorRecord* rec = mActiveSensors.valueFor(handle);
1019fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (rec) {
1020fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        // see if this connection becomes inactive
1021787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian        if (connection->removeSensor(handle)) {
1022787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian            BatteryService::disableSensor(connection->getUid(), handle);
1023787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian        }
1024fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        if (connection->hasAnySensor() == false) {
10258a96955c8e14db40b16164236830fc9506a00872Aravind Akella            connection->updateLooperRegistration(mLooper);
1026fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            mActiveConnections.remove(connection);
1027fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
1028fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        // see if this sensor becomes inactive
1029fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        if (rec->removeConnection(connection)) {
1030fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            mActiveSensors.removeItem(handle);
1031755c451c7861a029e26e5f16e319b629169e656dPeng Xu            mActiveVirtualSensors.erase(handle);
1032fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            delete rec;
1033fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
10344342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        return NO_ERROR;
10357c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    }
10364342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    return BAD_VALUE;
1037fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1038fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
10397c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianstatus_t SensorService::setEventRate(const sp<SensorEventConnection>& connection,
104047e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu        int handle, nsecs_t ns, const String16& opPackageName) {
104150df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian    if (mInitCheck != NO_ERROR)
104250df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian        return mInitCheck;
104350df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
1044755c451c7861a029e26e5f16e319b629169e656dPeng Xu    sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
1045755c451c7861a029e26e5f16e319b629169e656dPeng Xu    if (sensor == nullptr ||
1046755c451c7861a029e26e5f16e319b629169e656dPeng Xu        !canAccessSensor(sensor->getSensor(), "Tried configuring", opPackageName)) {
1047700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return BAD_VALUE;
1048700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
1049700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
10501cd700015318727d6d42236ab6274f1949fb08baMathias Agopian    if (ns < 0)
10511cd700015318727d6d42236ab6274f1949fb08baMathias Agopian        return BAD_VALUE;
10521cd700015318727d6d42236ab6274f1949fb08baMathias Agopian
105362569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian    nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
105462569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian    if (ns < minDelayNs) {
105562569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian        ns = minDelayNs;
1056ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian    }
1057ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian
1058f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    return sensor->setDelay(connection.get(), handle, ns);
1059fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1060fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1061b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslavstatus_t SensorService::flushSensor(const sp<SensorEventConnection>& connection,
1062b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        const String16& opPackageName) {
1063700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    if (mInitCheck != NO_ERROR) return mInitCheck;
10649e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    SensorDevice& dev(SensorDevice::getInstance());
10659e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    const int halVersion = dev.getHalDeviceVersion();
10669e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    status_t err(NO_ERROR);
10679e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    Mutex::Autolock _l(mLock);
10689e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    // Loop through all sensors for this connection and call flush on each of them.
10699e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    for (size_t i = 0; i < connection->mSensorInfo.size(); ++i) {
10709e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        const int handle = connection->mSensorInfo.keyAt(i);
1071755c451c7861a029e26e5f16e319b629169e656dPeng Xu        sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
1072755c451c7861a029e26e5f16e319b629169e656dPeng Xu        if (sensor == nullptr) {
1073755c451c7861a029e26e5f16e319b629169e656dPeng Xu            continue;
1074755c451c7861a029e26e5f16e319b629169e656dPeng Xu        }
10759e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
10769e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            ALOGE("flush called on a one-shot sensor");
10779e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            err = INVALID_OPERATION;
10789e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            continue;
10799e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        }
10808493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        if (halVersion <= SENSORS_DEVICE_API_VERSION_1_0 || isVirtualSensor(handle)) {
10819e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            // For older devices just increment pending flush count which will send a trivial
10829e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            // flush complete event.
10838a96955c8e14db40b16164236830fc9506a00872Aravind Akella            connection->incrementPendingFlushCount(handle);
10849e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        } else {
1085b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            if (!canAccessSensor(sensor->getSensor(), "Tried flushing", opPackageName)) {
1086b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                err = INVALID_OPERATION;
1087b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                continue;
1088b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            }
10899e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            status_t err_flush = sensor->flush(connection.get(), handle);
10909e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            if (err_flush == NO_ERROR) {
10919e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella                SensorRecord* rec = mActiveSensors.valueFor(handle);
10929e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella                if (rec != NULL) rec->addPendingFlushConnection(connection);
10939e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            }
10949e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            err = (err_flush != NO_ERROR) ? err_flush : err;
10959e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        }
10966c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    }
10979e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    return err;
1098700180487ffec09d9df1657b018a7caadac24b75Aravind Akella}
1099700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
1100b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslavbool SensorService::canAccessSensor(const Sensor& sensor, const char* operation,
1101b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        const String16& opPackageName) {
1102b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    const String8& requiredPermission = sensor.getRequiredPermission();
1103700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
1104b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (requiredPermission.length() <= 0) {
1105700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return true;
1106b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    }
1107b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav
1108b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    bool hasPermission = false;
1109b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav
1110b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    // Runtime permissions can't use the cache as they may change.
1111b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (sensor.isRequiredPermissionRuntime()) {
1112b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        hasPermission = checkPermission(String16(requiredPermission),
1113b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                IPCThreadState::self()->getCallingPid(), IPCThreadState::self()->getCallingUid());
1114700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    } else {
1115b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        hasPermission = PermissionCache::checkCallingPermission(String16(requiredPermission));
1116b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    }
1117b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav
1118b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (!hasPermission) {
1119b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        ALOGE("%s a sensor (%s) without holding its required permission: %s",
1120b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                operation, sensor.getName().string(), sensor.getRequiredPermission().string());
1121700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return false;
1122700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
1123b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav
1124b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    const int32_t opCode = sensor.getRequiredAppOp();
1125b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (opCode >= 0) {
1126b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        AppOpsManager appOps;
1127b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        if (appOps.noteOp(opCode, IPCThreadState::self()->getCallingUid(), opPackageName)
1128b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                        != AppOpsManager::MODE_ALLOWED) {
1129d4036b6b7f9609fe09efabdbfbb8c8f9428f76f7Andreas Gampe            ALOGE("%s a sensor (%s) without enabled required app op: %d",
1130b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                    operation, sensor.getName().string(), opCode);
1131b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            return false;
1132b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        }
1133b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    }
1134b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav
1135b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    return true;
1136700180487ffec09d9df1657b018a7caadac24b75Aravind Akella}
1137700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
11389a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockState() {
11399a844cf78f09953145200b4074d47589257a408cAravind Akella    Mutex::Autolock _l(mLock);
11409a844cf78f09953145200b4074d47589257a408cAravind Akella    checkWakeLockStateLocked();
11419a844cf78f09953145200b4074d47589257a408cAravind Akella}
11429a844cf78f09953145200b4074d47589257a408cAravind Akella
11439a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockStateLocked() {
11449a844cf78f09953145200b4074d47589257a408cAravind Akella    if (!mWakeLockAcquired) {
11459a844cf78f09953145200b4074d47589257a408cAravind Akella        return;
11469a844cf78f09953145200b4074d47589257a408cAravind Akella    }
11479a844cf78f09953145200b4074d47589257a408cAravind Akella    bool releaseLock = true;
11489a844cf78f09953145200b4074d47589257a408cAravind Akella    for (size_t i=0 ; i<mActiveConnections.size() ; i++) {
11499a844cf78f09953145200b4074d47589257a408cAravind Akella        sp<SensorEventConnection> connection(mActiveConnections[i].promote());
11509a844cf78f09953145200b4074d47589257a408cAravind Akella        if (connection != 0) {
11519a844cf78f09953145200b4074d47589257a408cAravind Akella            if (connection->needsWakeLock()) {
11529a844cf78f09953145200b4074d47589257a408cAravind Akella                releaseLock = false;
11539a844cf78f09953145200b4074d47589257a408cAravind Akella                break;
11549a844cf78f09953145200b4074d47589257a408cAravind Akella            }
11559a844cf78f09953145200b4074d47589257a408cAravind Akella        }
11569a844cf78f09953145200b4074d47589257a408cAravind Akella    }
11579a844cf78f09953145200b4074d47589257a408cAravind Akella    if (releaseLock) {
1158b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        setWakeLockAcquiredLocked(false);
1159b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    }
1160b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
1161b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
1162b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::sendEventsFromCache(const sp<SensorEventConnection>& connection) {
1163b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    Mutex::Autolock _l(mLock);
1164b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    connection->writeToSocketFromCache();
1165b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    if (connection->needsWakeLock()) {
1166b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        setWakeLockAcquiredLocked(true);
1167b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    }
1168b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
1169b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
1170b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::populateActiveConnections(
1171b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        SortedVector< sp<SensorEventConnection> >* activeConnections) {
1172b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    Mutex::Autolock _l(mLock);
1173b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    for (size_t i=0 ; i < mActiveConnections.size(); ++i) {
1174b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        sp<SensorEventConnection> connection(mActiveConnections[i].promote());
1175b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        if (connection != 0) {
1176b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            activeConnections->add(connection);
1177b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        }
11789a844cf78f09953145200b4074d47589257a408cAravind Akella    }
11799a844cf78f09953145200b4074d47589257a408cAravind Akella}
11806c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
11814949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akellabool SensorService::isWhiteListedPackage(const String8& packageName) {
1182841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    return (packageName.contains(mWhiteListedPackage.string()));
11834949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella}
11844949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
1185fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}; // namespace android
1186fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1187