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 ®_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 ®_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