SensorService.cpp revision eb4d628b69831d533f14c09fd63400f75e69ba76
1fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian/* 2fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * Copyright (C) 2010 The Android Open Source Project 3fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * 4fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 5fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * you may not use this file except in compliance with the License. 6fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * You may obtain a copy of the License at 7fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * 8fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 9fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * 10fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * Unless required by applicable law or agreed to in writing, software 11fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 12fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * See the License for the specific language governing permissions and 14fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * limitations under the License. 15fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian */ 16fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 173301542828febc768e1df42892cfac4992c35474Mathias Agopian#include <cutils/properties.h> 183301542828febc768e1df42892cfac4992c35474Mathias Agopian 19b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav#include <binder/AppOpsManager.h> 20fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <binder/BinderService.h> 21451beee076cac09f817abae78a990dea108a9482Mathias Agopian#include <binder/IServiceManager.h> 221cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian#include <binder/PermissionCache.h> 23fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 24907103bf186cfdd2ed9eb3b6c36de53ade7b16f6Mathias Agopian#include <gui/SensorEventQueue.h> 25fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 26fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <hardware/sensors.h> 274342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh#include <hardware_legacy/power.h> 28fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 29787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian#include "BatteryService.h" 30984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "CorrectedGyroSensor.h" 31f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "GravitySensor.h" 32f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "LinearAccelerationSensor.h" 33984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "OrientationSensor.h" 34f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "RotationVectorSensor.h" 35984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "SensorFusion.h" 36eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu 37984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "SensorService.h" 38eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include "SensorEventConnection.h" 39eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include "SensorEventAckReceiver.h" 40eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include "SensorRecord.h" 41eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include "SensorRegistrationInfo.h" 42eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include "MostRecentEventLogger.h" 43eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu 44eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <inttypes.h> 45eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <math.h> 46eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <stdint.h> 47eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <sys/types.h> 48eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <sys/socket.h> 49fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 50fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopiannamespace android { 51fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// --------------------------------------------------------------------------- 52fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 533301542828febc768e1df42892cfac4992c35474Mathias Agopian/* 543301542828febc768e1df42892cfac4992c35474Mathias Agopian * Notes: 553301542828febc768e1df42892cfac4992c35474Mathias Agopian * 563301542828febc768e1df42892cfac4992c35474Mathias Agopian * - what about a gyro-corrected magnetic-field sensor? 573301542828febc768e1df42892cfac4992c35474Mathias Agopian * - run mag sensor from time to time to force calibration 583301542828febc768e1df42892cfac4992c35474Mathias Agopian * - gravity sensor length is wrong (=> drift in linear-acc sensor) 593301542828febc768e1df42892cfac4992c35474Mathias Agopian * 603301542828febc768e1df42892cfac4992c35474Mathias Agopian */ 613301542828febc768e1df42892cfac4992c35474Mathias Agopian 628ef3c89eb2030395f8a342bd16dbb344957ab275Aravind Akellaconst char* SensorService::WAKE_LOCK_NAME = "SensorService_wakelock"; 63a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella// Permissions. 64a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatic const String16 sDump("android.permission.DUMP"); 654342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 66fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorService() 678a96955c8e14db40b16164236830fc9506a00872Aravind Akella : mInitCheck(NO_INIT), mSocketBufferSize(SOCKET_BUFFER_SIZE_NON_BATCHED), 688a96955c8e14db40b16164236830fc9506a00872Aravind Akella mWakeLockAcquired(false) 69fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 70fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 71fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 72fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianvoid SensorService::onFirstRef() 73fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 74a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block ALOGD("nuSensorService starting..."); 75f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian SensorDevice& dev(SensorDevice::getInstance()); 76fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 77f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian if (dev.initCheck() == NO_ERROR) { 78f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sensor_t const* list; 797b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian ssize_t count = dev.getSensorList(&list); 807b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian if (count > 0) { 817b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian ssize_t orientationIndex = -1; 82f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella bool hasGyro = false, hasAccel = false, hasMag = false; 837b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian uint32_t virtualSensorsNeeds = 847b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian (1<<SENSOR_TYPE_GRAVITY) | 857b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian (1<<SENSOR_TYPE_LINEAR_ACCELERATION) | 86f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu (1<<SENSOR_TYPE_ROTATION_VECTOR) | 87f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR) | 88f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR); 897b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian 907b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian mLastEventSeen.setCapacity(count); 917b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian for (ssize_t i=0 ; i<count ; i++) { 92f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu bool useThisSensor=true; 93f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu 947b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian switch (list[i].type) { 95f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella case SENSOR_TYPE_ACCELEROMETER: 96f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella hasAccel = true; 97f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella break; 98f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella case SENSOR_TYPE_MAGNETIC_FIELD: 99f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella hasMag = true; 100f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella break; 1017b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian case SENSOR_TYPE_ORIENTATION: 1027b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian orientationIndex = i; 1037b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian break; 1047b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian case SENSOR_TYPE_GYROSCOPE: 1050319306670b0344da99efa606b6f172dde575a39Mathias Agopian case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED: 1067b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian hasGyro = true; 1077b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian break; 1087b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian case SENSOR_TYPE_GRAVITY: 1097b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian case SENSOR_TYPE_LINEAR_ACCELERATION: 1107b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian case SENSOR_TYPE_ROTATION_VECTOR: 111f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR: 112f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu case SENSOR_TYPE_GAME_ROTATION_VECTOR: 113f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu if (IGNORE_HARDWARE_FUSION) { 114f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu useThisSensor = false; 115f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu } else { 116f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu virtualSensorsNeeds &= ~(1<<list[i].type); 117f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu } 1187b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian break; 1197b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian } 120f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu if (useThisSensor) { 121f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu registerSensor( new HardwareSensor(list[i]) ); 122f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu } 12350df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian } 124fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 1257b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian // it's safe to instantiate the SensorFusion object here 1267b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian // (it wants to be instantiated after h/w sensors have been 1277b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian // registered) 128d4036b6b7f9609fe09efabdbfbb8c8f9428f76f7Andreas Gampe SensorFusion::getInstance(); 1297b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian 1300319306670b0344da99efa606b6f172dde575a39Mathias Agopian // build the sensor list returned to users 1310319306670b0344da99efa606b6f172dde575a39Mathias Agopian mUserSensorList = mSensorList; 1320319306670b0344da99efa606b6f172dde575a39Mathias Agopian 133f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella if (hasGyro && hasAccel && hasMag) { 1340319306670b0344da99efa606b6f172dde575a39Mathias Agopian // Add Android virtual sensors if they're not already 1350319306670b0344da99efa606b6f172dde575a39Mathias Agopian // available in the HAL 136f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu Sensor aSensor; 1377b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian 1380319306670b0344da99efa606b6f172dde575a39Mathias Agopian aSensor = registerVirtualSensor( new RotationVectorSensor() ); 1390319306670b0344da99efa606b6f172dde575a39Mathias Agopian if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) { 1400319306670b0344da99efa606b6f172dde575a39Mathias Agopian mUserSensorList.add(aSensor); 1410319306670b0344da99efa606b6f172dde575a39Mathias Agopian } 142f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 1430319306670b0344da99efa606b6f172dde575a39Mathias Agopian aSensor = registerVirtualSensor( new OrientationSensor() ); 1440319306670b0344da99efa606b6f172dde575a39Mathias Agopian if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) { 1450319306670b0344da99efa606b6f172dde575a39Mathias Agopian // if we are doing our own rotation-vector, also add 1460319306670b0344da99efa606b6f172dde575a39Mathias Agopian // the orientation sensor and remove the HAL provided one. 1470319306670b0344da99efa606b6f172dde575a39Mathias Agopian mUserSensorList.replaceAt(aSensor, orientationIndex); 1487b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian } 1490319306670b0344da99efa606b6f172dde575a39Mathias Agopian 150f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu aSensor = registerVirtualSensor( 151f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu new LinearAccelerationSensor(list, count) ); 152f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu if (virtualSensorsNeeds & 153f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) { 154f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu mUserSensorList.add(aSensor); 155f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu } 156f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu 1570319306670b0344da99efa606b6f172dde575a39Mathias Agopian // virtual debugging sensors are not added to mUserSensorList 1580319306670b0344da99efa606b6f172dde575a39Mathias Agopian registerVirtualSensor( new CorrectedGyroSensor(list, count) ); 1590319306670b0344da99efa606b6f172dde575a39Mathias Agopian registerVirtualSensor( new GyroDriftSensor() ); 160010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian } 161010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian 162f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu if (hasAccel && hasGyro) { 163f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu Sensor aSensor; 164f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu 165f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu aSensor = registerVirtualSensor( 166f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu new GravitySensor(list, count) ); 167f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu if (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) { 168f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu mUserSensorList.add(aSensor); 169f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu } 170f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu 171f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu aSensor = registerVirtualSensor( 172f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu new GameRotationVectorSensor() ); 173f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu if (virtualSensorsNeeds & 174f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR)) { 175f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu mUserSensorList.add(aSensor); 176f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu } 177f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu } 178f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu 179f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu if (hasAccel && hasMag) { 180f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu Sensor aSensor; 181f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu 182f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu aSensor = registerVirtualSensor( 183f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu new GeoMagRotationVectorSensor() ); 184f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu if (virtualSensorsNeeds & 185f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR)) { 186f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu mUserSensorList.add(aSensor); 187f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu } 188f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu } 189f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu 19033264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian // debugging sensor list 1910319306670b0344da99efa606b6f172dde575a39Mathias Agopian mUserSensorListDebug = mSensorList; 19233264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian 1935466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // Check if the device really supports batching by looking at the FIFO event 1945466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // counts for each sensor. 1955466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella bool batchingSupported = false; 196b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav for (size_t i = 0; i < mSensorList.size(); ++i) { 1975466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella if (mSensorList[i].getFifoMaxEventCount() > 0) { 1985466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella batchingSupported = true; 1995466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella break; 2005466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella } 2015466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella } 2025466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella 2035466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella if (batchingSupported) { 2045466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // Increase socket buffer size to a max of 100 KB for batching capabilities. 2055466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella mSocketBufferSize = MAX_SOCKET_BUFFER_SIZE_BATCHED; 2065466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella } else { 2075466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella mSocketBufferSize = SOCKET_BUFFER_SIZE_NON_BATCHED; 2085466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella } 2095466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella 2105466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // Compare the socketBufferSize value against the system limits and limit 2115466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // it to maxSystemSocketBufferSize if necessary. 2124c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella FILE *fp = fopen("/proc/sys/net/core/wmem_max", "r"); 2134c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella char line[128]; 2144c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella if (fp != NULL && fgets(line, sizeof(line), fp) != NULL) { 2154c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella line[sizeof(line) - 1] = '\0'; 2165466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella size_t maxSystemSocketBufferSize; 2175466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella sscanf(line, "%zu", &maxSystemSocketBufferSize); 2185466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella if (mSocketBufferSize > maxSystemSocketBufferSize) { 2195466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella mSocketBufferSize = maxSystemSocketBufferSize; 2204c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 2214c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 2224c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella if (fp) { 2234c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella fclose(fp); 2244c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 2254c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella 2269a844cf78f09953145200b4074d47589257a408cAravind Akella mWakeLockAcquired = false; 22756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella mLooper = new Looper(false); 2288493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT; 2298493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mSensorEventBuffer = new sensors_event_t[minBufferSize]; 2308493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mSensorEventScratch = new sensors_event_t[minBufferSize]; 2318493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize]; 232a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella mCurrentOperatingMode = NORMAL; 2337830ef3dd0ff3749d974c2dd85a8fa59dc47aecaAravind Akella 23418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mNextSensorRegIndex = 0; 23518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella for (int i = 0; i < SENSOR_REGISTRATIONS_BUF_SIZE; ++i) { 23618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mLastNSensorRegistrations.push(); 23718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } 23818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella 23918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mInitCheck = NO_ERROR; 240b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mAckReceiver = new SensorEventAckReceiver(this); 241b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY); 2427830ef3dd0ff3749d974c2dd85a8fa59dc47aecaAravind Akella run("SensorService", PRIORITY_URGENT_DISPLAY); 2437b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian } 244fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 245fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 246fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 2470319306670b0344da99efa606b6f172dde575a39Mathias AgopianSensor SensorService::registerSensor(SensorInterface* s) 248f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{ 249f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sensors_event_t event; 250f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian memset(&event, 0, sizeof(event)); 251f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 252f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian const Sensor sensor(s->getSensor()); 253f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian // add to the sensor list (returned to clients) 254f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian mSensorList.add(sensor); 255f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian // add to our handle->SensorInterface mapping 256f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian mSensorMap.add(sensor.getHandle(), s); 257f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian // create an entry in the mLastEventSeen array 258444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella mLastEventSeen.add(sensor.getHandle(), NULL); 2590319306670b0344da99efa606b6f172dde575a39Mathias Agopian 2600319306670b0344da99efa606b6f172dde575a39Mathias Agopian return sensor; 261f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian} 262f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 2630319306670b0344da99efa606b6f172dde575a39Mathias AgopianSensor SensorService::registerVirtualSensor(SensorInterface* s) 264f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{ 2650319306670b0344da99efa606b6f172dde575a39Mathias Agopian Sensor sensor = registerSensor(s); 266f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian mVirtualSensorList.add( s ); 2670319306670b0344da99efa606b6f172dde575a39Mathias Agopian return sensor; 268f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian} 269f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 270fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::~SensorService() 271fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 272f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian for (size_t i=0 ; i<mSensorMap.size() ; i++) 273f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian delete mSensorMap.valueAt(i); 274fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 275fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 2764949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akellastatus_t SensorService::dump(int fd, const Vector<String16>& args) 277fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 278fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian String8 result; 2791cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian if (!PermissionCache::checkCallingPermission(sDump)) { 280eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu result.appendFormat("Permission Denial: can't dump SensorService from pid=%d, uid=%d\n", 281fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian IPCThreadState::self()->getCallingPid(), 282fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian IPCThreadState::self()->getCallingUid()); 283444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } else { 284841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (args.size() > 2) { 2854949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella return INVALID_OPERATION; 2864949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella } 2874949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella Mutex::Autolock _l(mLock); 2884949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella SensorDevice& dev(SensorDevice::getInstance()); 289841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (args.size() == 2 && args[0] == String16("restrict")) { 290444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // If already in restricted mode. Ignore. 291444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (mCurrentOperatingMode == RESTRICTED) { 292444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella return status_t(NO_ERROR); 293444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 294444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // If in any mode other than normal, ignore. 295444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (mCurrentOperatingMode != NORMAL) { 296444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella return INVALID_OPERATION; 297444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 298a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella mCurrentOperatingMode = RESTRICTED; 2994949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella dev.disableAllSensors(); 3004949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella // Clear all pending flush connections for all active sensors. If one of the active 3014949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella // connections has called flush() and the underlying sensor has been disabled before a 3024949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella // flush complete event is returned, we need to remove the connection from this queue. 3034949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella for (size_t i=0 ; i< mActiveSensors.size(); ++i) { 3044949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella mActiveSensors.valueAt(i)->clearAllPendingFlushConnections(); 3054949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella } 306841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella mWhiteListedPackage.setTo(String8(args[1])); 307444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella return status_t(NO_ERROR); 308444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } else if (args.size() == 1 && args[0] == String16("enable")) { 309444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // If currently in restricted mode, reset back to NORMAL mode else ignore. 310444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (mCurrentOperatingMode == RESTRICTED) { 311444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella mCurrentOperatingMode = NORMAL; 312444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella dev.enableAllSensors(); 3136c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } 314841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (mCurrentOperatingMode == DATA_INJECTION) { 315841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella resetToNormalModeLocked(); 316841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } 317841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella mWhiteListedPackage.clear(); 318444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella return status_t(NO_ERROR); 319841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } else if (args.size() == 2 && args[0] == String16("data_injection")) { 320841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (mCurrentOperatingMode == NORMAL) { 321841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella dev.disableAllSensors(); 322841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella status_t err = dev.setMode(DATA_INJECTION); 323841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (err == NO_ERROR) { 324841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella mCurrentOperatingMode = DATA_INJECTION; 325841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } else { 326841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella // Re-enable sensors. 327841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella dev.enableAllSensors(); 328841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } 329841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella mWhiteListedPackage.setTo(String8(args[1])); 330841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella return NO_ERROR; 331841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } else if (mCurrentOperatingMode == DATA_INJECTION) { 332841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella // Already in DATA_INJECTION mode. Treat this as a no_op. 333841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella return NO_ERROR; 334841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } else { 335841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella // Transition to data injection mode supported only from NORMAL mode. 336841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella return INVALID_OPERATION; 337841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } 338ee155cadb23e84542cbf445c2aac89ae63df4cc7Aravind Akella } else if (mSensorList.size() == 0) { 339ee155cadb23e84542cbf445c2aac89ae63df4cc7Aravind Akella result.append("No Sensors on the device\n"); 340444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } else { 341444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // Default dump the sensor list and debugging information. 342444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.append("Sensor List:\n"); 343444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella for (size_t i=0 ; i<mSensorList.size() ; i++) { 344444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella const Sensor& s(mSensorList[i]); 345444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat( 346444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella "%-15s| %-10s| version=%d |%-20s| 0x%08x | \"%s\" | type=%d |", 347444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella s.getName().string(), 348444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella s.getVendor().string(), 349444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella s.getVersion(), 350444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella s.getStringType().string(), 351444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella s.getHandle(), 352444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella s.getRequiredPermission().string(), 353444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella s.getType()); 354444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella 355444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella const int reportingMode = s.getReportingMode(); 356444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (reportingMode == AREPORTING_MODE_CONTINUOUS) { 357444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.append(" continuous | "); 358444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } else if (reportingMode == AREPORTING_MODE_ON_CHANGE) { 359444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.append(" on-change | "); 360444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } else if (reportingMode == AREPORTING_MODE_ONE_SHOT) { 361444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.append(" one-shot | "); 362444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } else { 363444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.append(" special-trigger | "); 364444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 3656c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 366444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (s.getMaxDelay() > 0) { 367444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat("minRate=%.2fHz | ", 1e6f / s.getMaxDelay()); 368444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } else { 369444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat("maxDelay=%dus |", s.getMaxDelay()); 370444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 3710e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella 372444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (s.getMinDelay() > 0) { 373444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat("maxRate=%.2fHz | ", 1e6f / s.getMinDelay()); 374444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } else { 375444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat("minDelay=%dus |", s.getMinDelay()); 376444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 3770e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella 378444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (s.getFifoMaxEventCount() > 0) { 379444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat("FifoMax=%d events | ", 380444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella s.getFifoMaxEventCount()); 381444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } else { 382444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.append("no batching | "); 383444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 3846c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 385444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (s.isWakeUpSensor()) { 386444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat("wakeUp | "); 387444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } else { 388444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat("non-wakeUp | "); 389444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 390ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian 39118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella int bufIndex = mLastEventSeen.indexOfKey(s.getHandle()); 39218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella if (bufIndex >= 0) { 393eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu const MostRecentEventLogger* buf = mLastEventSeen.valueAt(bufIndex); 39418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella if (buf != NULL && s.getRequiredPermission().isEmpty()) { 39518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella buf->printBuffer(result); 39618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } else { 39718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella result.append("last=<> \n"); 39818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } 399444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 400444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.append("\n"); 401444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 402444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella SensorFusion::getInstance().dump(result); 403444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella SensorDevice::getInstance().dump(result); 404444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella 405444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.append("Active sensors:\n"); 406444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella for (size_t i=0 ; i<mActiveSensors.size() ; i++) { 407444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella int handle = mActiveSensors.keyAt(i); 408444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat("%s (handle=0x%08x, connections=%zu)\n", 409444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella getSensorName(handle).string(), 410444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella handle, 411444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella mActiveSensors.valueAt(i)->getNumConnections()); 412ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian } 4134c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella 414d4036b6b7f9609fe09efabdbfbb8c8f9428f76f7Andreas Gampe result.appendFormat("Socket Buffer size = %zd events\n", 415444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella mSocketBufferSize/sizeof(sensors_event_t)); 41618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella result.appendFormat("WakeLock Status: %s \n", mWakeLockAcquired ? "acquired" : 41718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella "not held"); 418444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat("Mode :"); 419444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella switch(mCurrentOperatingMode) { 420444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella case NORMAL: 421444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat(" NORMAL\n"); 422444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella break; 423444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella case RESTRICTED: 424841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella result.appendFormat(" RESTRICTED : %s\n", mWhiteListedPackage.string()); 425444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella break; 426444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella case DATA_INJECTION: 427841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella result.appendFormat(" DATA_INJECTION : %s\n", mWhiteListedPackage.string()); 428444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 429444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat("%zd active connections\n", mActiveConnections.size()); 4304c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella 431444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella for (size_t i=0 ; i < mActiveConnections.size() ; i++) { 432444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella sp<SensorEventConnection> connection(mActiveConnections[i].promote()); 433444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (connection != 0) { 434444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat("Connection Number: %zu \n", i); 435444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella connection->dump(result); 436444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 4374c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 43818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella 43918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella result.appendFormat("Previous Registrations:\n"); 44018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella // Log in the reverse chronological order. 44118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella int currentIndex = (mNextSensorRegIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) % 44218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella SENSOR_REGISTRATIONS_BUF_SIZE; 44318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella const int startIndex = currentIndex; 44418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella do { 44518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella const SensorRegistrationInfo& reg_info = mLastNSensorRegistrations[currentIndex]; 44618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella if (SensorRegistrationInfo::isSentinel(reg_info)) { 44718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella // Ignore sentinel, proceed to next item. 44818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella currentIndex = (currentIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) % 44918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella SENSOR_REGISTRATIONS_BUF_SIZE; 45018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella continue; 45118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } 45218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella if (reg_info.mActivated) { 45318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella result.appendFormat("%02d:%02d:%02d activated package=%s handle=0x%08x " 45418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella "samplingRate=%dus maxReportLatency=%dus\n", 45518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mHour, reg_info.mMin, reg_info.mSec, 45618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mPackageName.string(), reg_info.mSensorHandle, 45718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mSamplingRateUs, reg_info.mMaxReportLatencyUs); 45818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } else { 45918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella result.appendFormat("%02d:%02d:%02d de-activated package=%s handle=0x%08x\n", 46018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mHour, reg_info.mMin, reg_info.mSec, 46118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mPackageName.string(), reg_info.mSensorHandle); 46218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } 46318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella currentIndex = (currentIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) % 46418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella SENSOR_REGISTRATIONS_BUF_SIZE; 46518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } while(startIndex != currentIndex); 4664c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 467fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 468fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian write(fd, result.string(), result.size()); 469fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return NO_ERROR; 470fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 471fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 4729a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::cleanupAutoDisabledSensorLocked(const sp<SensorEventConnection>& connection, 4734342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh sensors_event_t const* buffer, const int count) { 4744342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh for (int i=0 ; i<count ; i++) { 4754342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh int handle = buffer[i].sensor; 4768493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (buffer[i].type == SENSOR_TYPE_META_DATA) { 4778493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella handle = buffer[i].meta_data.sensor; 4788493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } 4790e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella if (connection->hasSensor(handle)) { 4800e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella SensorInterface* sensor = mSensorMap.valueFor(handle); 4810e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella // If this buffer has an event from a one_shot sensor and this connection is registered 4820e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella // for this particular one_shot sensor, try cleaning up the connection. 4830e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella if (sensor != NULL && 4840e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) { 4850e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella sensor->autoDisable(connection.get(), handle); 4869a844cf78f09953145200b4074d47589257a408cAravind Akella cleanupWithoutDisableLocked(connection, handle); 4874342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 488a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella 4894342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 490a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella } 4914342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh} 4924342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 493fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::threadLoop() 494fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 495a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block ALOGD("nuSensorService thread starting..."); 496fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 497eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // each virtual sensor could generate an event per "real" event, that's why we need to size 498eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT. in practice, this is too 499eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // aggressive, but guaranteed to be enough. 50090ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT; 50190ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian const size_t numEventMax = minBufferSize / (1 + mVirtualSensorList.size()); 50290ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian 503f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian SensorDevice& device(SensorDevice::getInstance()); 504f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian const size_t vcount = mVirtualSensorList.size(); 505fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 5064342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh const int halVersion = device.getHalDeviceVersion(); 507fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian do { 5088493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella ssize_t count = device.poll(mSensorEventBuffer, numEventMax); 5098493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (count < 0) { 510f5a1230d322c14c42331d0a1536b50c87742973bSteve Block ALOGE("sensor poll failed (%s)", strerror(-count)); 511fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian break; 512fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 51356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 51456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // Reset sensors_event_t.flags to zero for all events in the buffer. 51556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella for (int i = 0; i < count; i++) { 5168493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mSensorEventBuffer[i].flags = 0; 51756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 518e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella 519eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // Make a copy of the connection vector as some connections may be removed during the course 520eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // of this loop (especially when one-shot sensor events are present in the sensor_event 521eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // buffer). Promote all connections to StrongPointers before the lock is acquired. If the 522eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // destructor of the sp gets called when the lock is acquired, it may result in a deadlock 523eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // as ~SensorEventConnection() needs to acquire mLock again for cleanup. So copy all the 524eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // strongPointers to a vector before the lock is acquired. 525e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella SortedVector< sp<SensorEventConnection> > activeConnections; 526b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella populateActiveConnections(&activeConnections); 527eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu 5289a844cf78f09953145200b4074d47589257a408cAravind Akella Mutex::Autolock _l(mLock); 5299a844cf78f09953145200b4074d47589257a408cAravind Akella // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The 5309a844cf78f09953145200b4074d47589257a408cAravind Akella // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock, 5319a844cf78f09953145200b4074d47589257a408cAravind Akella // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should 5329a844cf78f09953145200b4074d47589257a408cAravind Akella // not be interleaved with decrementing SensorEventConnection::mWakeLockRefCount and 5339a844cf78f09953145200b4074d47589257a408cAravind Akella // releasing the wakelock. 5349a844cf78f09953145200b4074d47589257a408cAravind Akella bool bufferHasWakeUpEvent = false; 5354342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh for (int i = 0; i < count; i++) { 5368493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (isWakeUpSensorEvent(mSensorEventBuffer[i])) { 5379a844cf78f09953145200b4074d47589257a408cAravind Akella bufferHasWakeUpEvent = true; 5389a844cf78f09953145200b4074d47589257a408cAravind Akella break; 5394342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 5404342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 5414342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 5429a844cf78f09953145200b4074d47589257a408cAravind Akella if (bufferHasWakeUpEvent && !mWakeLockAcquired) { 543b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella setWakeLockAcquiredLocked(true); 5449a844cf78f09953145200b4074d47589257a408cAravind Akella } 5458493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella recordLastValueLocked(mSensorEventBuffer, count); 54694e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian 547f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian // handle virtual sensors 548f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian if (count && vcount) { 5498493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella sensors_event_t const * const event = mSensorEventBuffer; 5509a844cf78f09953145200b4074d47589257a408cAravind Akella const size_t activeVirtualSensorCount = mActiveVirtualSensors.size(); 551f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian if (activeVirtualSensorCount) { 552f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian size_t k = 0; 553984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian SensorFusion& fusion(SensorFusion::getInstance()); 554984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian if (fusion.isEnabled()) { 555984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t i=0 ; i<size_t(count) ; i++) { 556984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian fusion.process(event[i]); 557984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 558984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 559d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) { 560f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian for (size_t j=0 ; j<activeVirtualSensorCount ; j++) { 561d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian if (count + k >= minBufferSize) { 562d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian ALOGE("buffer too small to hold all events: " 563db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn "count=%zd, k=%zu, size=%zu", 564d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian count, k, minBufferSize); 565d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian break; 566d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian } 567f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sensors_event_t out; 5689a844cf78f09953145200b4074d47589257a408cAravind Akella SensorInterface* si = mActiveVirtualSensors.valueAt(j); 569d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian if (si->process(&out, event[i])) { 5708493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mSensorEventBuffer[count + k] = out; 571f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian k++; 572f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 573f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 574f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 575f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian if (k) { 576f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian // record the last synthesized values 5778493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella recordLastValueLocked(&mSensorEventBuffer[count], k); 578f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian count += k; 579f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian // sort the buffer by time-stamps 5808493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella sortEventBuffer(mSensorEventBuffer, count); 581f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 582f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 583f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 584f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 5854342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // handle backward compatibility for RotationVector sensor 5864342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) { 5874342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh for (int i = 0; i < count; i++) { 5888493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (mSensorEventBuffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) { 5894342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // All the 4 components of the quaternion should be available 5904342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // No heading accuracy. Set it to -1 5918493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mSensorEventBuffer[i].data[4] = -1; 5928493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } 5938493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } 5948493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } 5958493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella 596eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // Map flush_complete_events in the buffer to SensorEventConnections which called flush on 597eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // the hardware sensor. mapFlushEventsToConnections[i] will be the SensorEventConnection 598eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // mapped to the corresponding flush_complete_event in mSensorEventBuffer[i] if such a 599eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // mapping exists (NULL otherwise). 6008493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella for (int i = 0; i < count; ++i) { 6018493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mMapFlushEventsToConnections[i] = NULL; 6028493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (mSensorEventBuffer[i].type == SENSOR_TYPE_META_DATA) { 6038493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella const int sensor_handle = mSensorEventBuffer[i].meta_data.sensor; 6048493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella SensorRecord* rec = mActiveSensors.valueFor(sensor_handle); 6058493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (rec != NULL) { 6068493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mMapFlushEventsToConnections[i] = rec->getFirstPendingFlushConnection(); 6078493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella rec->removeFirstPendingFlushConnection(); 6084342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 6094342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 6104342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 6114342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 6129a844cf78f09953145200b4074d47589257a408cAravind Akella // Send our events to clients. Check the state of wake lock for each client and release the 6139a844cf78f09953145200b4074d47589257a408cAravind Akella // lock if none of the clients need it. 6149a844cf78f09953145200b4074d47589257a408cAravind Akella bool needsWakeLock = false; 6158493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella size_t numConnections = activeConnections.size(); 6168493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella for (size_t i=0 ; i < numConnections; ++i) { 617e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella if (activeConnections[i] != 0) { 618e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch, 6198493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mMapFlushEventsToConnections); 620e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella needsWakeLock |= activeConnections[i]->needsWakeLock(); 6218493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella // If the connection has one-shot sensors, it may be cleaned up after first trigger. 6228493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella // Early check for one-shot sensors. 623e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella if (activeConnections[i]->hasOneShotSensors()) { 624e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer, 625e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella count); 6268493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } 627fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 628fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 6294342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 6309a844cf78f09953145200b4074d47589257a408cAravind Akella if (mWakeLockAcquired && !needsWakeLock) { 631b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella setWakeLockAcquiredLocked(false); 6329a844cf78f09953145200b4074d47589257a408cAravind Akella } 6338493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } while (!Thread::exitPending()); 634fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 6353c20fbed7f3a916ced10f2ed5a272271b7d81edeSteve Block ALOGW("Exiting SensorService::threadLoop => aborting..."); 6361a62301fc58cd2af18239b0415813461bf5fc41bMathias Agopian abort(); 637fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return false; 638fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 639fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 64056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellasp<Looper> SensorService::getLooper() const { 64156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella return mLooper; 64256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella} 64356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 644b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::resetAllWakeLockRefCounts() { 645b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella SortedVector< sp<SensorEventConnection> > activeConnections; 646b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella populateActiveConnections(&activeConnections); 647b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella { 648b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella Mutex::Autolock _l(mLock); 649b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella for (size_t i=0 ; i < activeConnections.size(); ++i) { 650b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (activeConnections[i] != 0) { 651b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella activeConnections[i]->resetWakeLockRefCount(); 652b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 653b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 654b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella setWakeLockAcquiredLocked(false); 655b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 656b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella} 657b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella 658b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::setWakeLockAcquiredLocked(bool acquire) { 659b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (acquire) { 660b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (!mWakeLockAcquired) { 661b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME); 662b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mWakeLockAcquired = true; 663b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 664b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mLooper->wake(); 665b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } else { 666b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (mWakeLockAcquired) { 667b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella release_wake_lock(WAKE_LOCK_NAME); 668b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mWakeLockAcquired = false; 669b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 670b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 671b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella} 672b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella 673b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellabool SensorService::isWakeLockAcquired() { 674b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella Mutex::Autolock _l(mLock); 675b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella return mWakeLockAcquired; 676b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella} 677b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella 67856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellabool SensorService::SensorEventAckReceiver::threadLoop() { 67956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella ALOGD("new thread SensorEventAckReceiver"); 680b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella sp<Looper> looper = mService->getLooper(); 68156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella do { 682b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella bool wakeLockAcquired = mService->isWakeLockAcquired(); 683b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella int timeout = -1; 684b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (wakeLockAcquired) timeout = 5000; 685b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella int ret = looper->pollOnce(timeout); 686b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (ret == ALOOPER_POLL_TIMEOUT) { 687b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mService->resetAllWakeLockRefCounts(); 688b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 68956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } while(!Thread::exitPending()); 69056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella return false; 69156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella} 69256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 6939a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::recordLastValueLocked( 6944b84704b97300eff3ebfab85652e64d54149d205Aravind Akella const sensors_event_t* buffer, size_t count) { 6954b84704b97300eff3ebfab85652e64d54149d205Aravind Akella for (size_t i = 0; i < count; i++) { 696444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (buffer[i].type != SENSOR_TYPE_META_DATA) { 697eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu MostRecentEventLogger* &circular_buf = mLastEventSeen.editValueFor(buffer[i].sensor); 698444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (circular_buf == NULL) { 699eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu circular_buf = new MostRecentEventLogger(buffer[i].type); 7004b84704b97300eff3ebfab85652e64d54149d205Aravind Akella } 701444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella circular_buf->addEvent(buffer[i]); 70294e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian } 70394e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian } 70494e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian} 70594e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian 706f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopianvoid SensorService::sortEventBuffer(sensors_event_t* buffer, size_t count) 707f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{ 708f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian struct compar { 709f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian static int cmp(void const* lhs, void const* rhs) { 710f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sensors_event_t const* l = static_cast<sensors_event_t const*>(lhs); 711f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sensors_event_t const* r = static_cast<sensors_event_t const*>(rhs); 712a5c106a4f0afcf061728a1cb7c8c3b908728575dMathias Agopian return l->timestamp - r->timestamp; 713f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 714f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian }; 715f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian qsort(buffer, count, sizeof(sensors_event_t), compar::cmp); 716f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian} 717f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 7185d2707214dfb97bd8dfcc6620be36841d3c82420Mathias AgopianString8 SensorService::getSensorName(int handle) const { 719010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian size_t count = mUserSensorList.size(); 7205d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian for (size_t i=0 ; i<count ; i++) { 721010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian const Sensor& sensor(mUserSensorList[i]); 7225d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian if (sensor.getHandle() == handle) { 7235d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian return sensor.getName(); 7245d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian } 7255d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian } 7265d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian String8 result("unknown"); 7275d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian return result; 7285d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian} 7295d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian 730b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akellabool SensorService::isVirtualSensor(int handle) const { 731b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella SensorInterface* sensor = mSensorMap.valueFor(handle); 732b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella return sensor->isVirtual(); 733b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella} 734b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella 7359a844cf78f09953145200b4074d47589257a408cAravind Akellabool SensorService::isWakeUpSensorEvent(const sensors_event_t& event) const { 7367869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan int handle = event.sensor; 7377869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan if (event.type == SENSOR_TYPE_META_DATA) { 7387869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan handle = event.meta_data.sensor; 7397869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan } 7407869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan SensorInterface* sensor = mSensorMap.valueFor(handle); 7417869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan return sensor != NULL && sensor->getSensor().isWakeUpSensor(); 7429a844cf78f09953145200b4074d47589257a408cAravind Akella} 7439a844cf78f09953145200b4074d47589257a408cAravind Akella 7446c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind AkellaSensorService::SensorRecord * SensorService::getSensorRecord(int handle) { 7456c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella return mActiveSensors.valueFor(handle); 7466c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella} 7476c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 748b412f6e203b38f8047f760261a5e3dc6d0722f08SvetoslavVector<Sensor> SensorService::getSensorList(const String16& opPackageName) 749fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 75033264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian char value[PROPERTY_VALUE_MAX]; 75133264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian property_get("debug.sensors", value, "0"); 752700180487ffec09d9df1657b018a7caadac24b75Aravind Akella const Vector<Sensor>& initialSensorList = (atoi(value)) ? 753700180487ffec09d9df1657b018a7caadac24b75Aravind Akella mUserSensorListDebug : mUserSensorList; 754700180487ffec09d9df1657b018a7caadac24b75Aravind Akella Vector<Sensor> accessibleSensorList; 755700180487ffec09d9df1657b018a7caadac24b75Aravind Akella for (size_t i = 0; i < initialSensorList.size(); i++) { 756700180487ffec09d9df1657b018a7caadac24b75Aravind Akella Sensor sensor = initialSensorList[i]; 757b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (canAccessSensor(sensor, "getSensorList", opPackageName)) { 758700180487ffec09d9df1657b018a7caadac24b75Aravind Akella accessibleSensorList.add(sensor); 759700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } else { 760b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav ALOGI("Skipped sensor %s because it requires permission %s and app op %d", 7615f6199373dc1e07d2ee5edbae7ecfa08a065492eBernhard Rosenkränzer sensor.getName().string(), 762b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav sensor.getRequiredPermission().string(), 763b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav sensor.getRequiredAppOp()); 764700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } 76533264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian } 766700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return accessibleSensorList; 767fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 768fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 769a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellasp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName, 770b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav int requestedMode, const String16& opPackageName) { 771a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella // Only 2 modes supported for a SensorEventConnection ... NORMAL and DATA_INJECTION. 772a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella if (requestedMode != NORMAL && requestedMode != DATA_INJECTION) { 773a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella return NULL; 774a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella } 775a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella 776a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella Mutex::Autolock _l(mLock); 777841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella // To create a client in DATA_INJECTION mode to inject data, SensorService should already be 778841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella // operating in DI mode. 779841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (requestedMode == DATA_INJECTION) { 780841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (mCurrentOperatingMode != DATA_INJECTION) return NULL; 781841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (!isWhiteListedPackage(packageName)) return NULL; 782841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } 783841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella 7845307d17fe33fc26eeeacd6339a9fbfe96cf56873Mathias Agopian uid_t uid = IPCThreadState::self()->getCallingUid(); 785a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella sp<SensorEventConnection> result(new SensorEventConnection(this, uid, packageName, 786b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav requestedMode == DATA_INJECTION, opPackageName)); 787a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella if (requestedMode == DATA_INJECTION) { 788a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella if (mActiveConnections.indexOf(result) < 0) { 789a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella mActiveConnections.add(result); 790a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella } 791a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella // Add the associated file descriptor to the Looper for polling whenever there is data to 792a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella // be injected. 793a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella result->updateLooperRegistration(mLooper); 794a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella } 795fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return result; 796fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 797fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 798841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akellaint SensorService::isDataInjectionEnabled() { 799a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella Mutex::Autolock _l(mLock); 800841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella return (mCurrentOperatingMode == DATA_INJECTION); 801a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella} 802a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella 803a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatus_t SensorService::resetToNormalMode() { 804a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella Mutex::Autolock _l(mLock); 805a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella return resetToNormalModeLocked(); 806a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella} 807a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella 808a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatus_t SensorService::resetToNormalModeLocked() { 809a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella SensorDevice& dev(SensorDevice::getInstance()); 810a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella dev.enableAllSensors(); 811a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella status_t err = dev.setMode(NORMAL); 812a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella mCurrentOperatingMode = NORMAL; 813a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella return err; 814a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella} 815a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella 816db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopianvoid SensorService::cleanupConnection(SensorEventConnection* c) 817fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 818fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian Mutex::Autolock _l(mLock); 819db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian const wp<SensorEventConnection> connection(c); 8207c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian size_t size = mActiveSensors.size(); 821db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn ALOGD_IF(DEBUG_CONNECTIONS, "%zu active sensors", size); 8227c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian for (size_t i=0 ; i<size ; ) { 823db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian int handle = mActiveSensors.keyAt(i); 824db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian if (c->hasSensor(handle)) { 825db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn ALOGD_IF(DEBUG_CONNECTIONS, "%zu: disabling handle=0x%08x", i, handle); 826f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian SensorInterface* sensor = mSensorMap.valueFor( handle ); 827f5a1230d322c14c42331d0a1536b50c87742973bSteve Block ALOGE_IF(!sensor, "mSensorMap[handle=0x%08x] is null!", handle); 828f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian if (sensor) { 829db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian sensor->activate(c, false); 830f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 8318a96955c8e14db40b16164236830fc9506a00872Aravind Akella c->removeSensor(handle); 832db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian } 833db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian SensorRecord* rec = mActiveSensors.valueAt(i); 834db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn ALOGE_IF(!rec, "mActiveSensors[%zu] is null (handle=0x%08x)!", i, handle); 835a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block ALOGD_IF(DEBUG_CONNECTIONS, 836db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn "removing connection %p for sensor[%zu].handle=0x%08x", 837a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian c, i, handle); 838a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian 839db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian if (rec && rec->removeConnection(connection)) { 840a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block ALOGD_IF(DEBUG_CONNECTIONS, "... and it was the last connection"); 8417c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian mActiveSensors.removeItemsAt(i, 1); 842f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian mActiveVirtualSensors.removeItem(handle); 8437c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian delete rec; 8447c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian size--; 8457c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian } else { 8467c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian i++; 847fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 848fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 8498a96955c8e14db40b16164236830fc9506a00872Aravind Akella c->updateLooperRegistration(mLooper); 8507c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian mActiveConnections.remove(connection); 851787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian BatteryService::cleanup(c->getUid()); 8529a844cf78f09953145200b4074d47589257a408cAravind Akella if (c->needsWakeLock()) { 8539a844cf78f09953145200b4074d47589257a408cAravind Akella checkWakeLockStateLocked(); 8549a844cf78f09953145200b4074d47589257a408cAravind Akella } 855fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 856fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 857700180487ffec09d9df1657b018a7caadac24b75Aravind AkellaSensor SensorService::getSensorFromHandle(int handle) const { 858700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return mSensorMap.valueFor(handle)->getSensor(); 859700180487ffec09d9df1657b018a7caadac24b75Aravind Akella} 860700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 861fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::enable(const sp<SensorEventConnection>& connection, 862b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags, 863b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav const String16& opPackageName) 864fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 86550df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian if (mInitCheck != NO_ERROR) 86650df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian return mInitCheck; 86750df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian 868f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian SensorInterface* sensor = mSensorMap.valueFor(handle); 869ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian if (sensor == NULL) { 870ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian return BAD_VALUE; 871ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian } 872700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 873b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (!canAccessSensor(sensor->getSensor(), "Tried enabling", opPackageName)) { 874700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return BAD_VALUE; 875700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } 876700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 877ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian Mutex::Autolock _l(mLock); 878841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if ((mCurrentOperatingMode == RESTRICTED || mCurrentOperatingMode == DATA_INJECTION) 879841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella && !isWhiteListedPackage(connection->getPackageName())) { 8804949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella return INVALID_OPERATION; 8814949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella } 8824949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella 8834342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh SensorRecord* rec = mActiveSensors.valueFor(handle); 8844342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (rec == 0) { 8854342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh rec = new SensorRecord(connection); 8864342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh mActiveSensors.add(handle, rec); 8874342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (sensor->isVirtual()) { 8884342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh mActiveVirtualSensors.add(handle, sensor); 8893560fb24b668675627934356f210d84d19bf4e56Mathias Agopian } 8904342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } else { 8914342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (rec->addConnection(connection)) { 8929a844cf78f09953145200b4074d47589257a408cAravind Akella // this sensor is already activated, but we are adding a connection that uses it. 8939a844cf78f09953145200b4074d47589257a408cAravind Akella // Immediately send down the last known value of the requested sensor if it's not a 8944342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // "continuous" sensor. 8950e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ON_CHANGE) { 8969a844cf78f09953145200b4074d47589257a408cAravind Akella // NOTE: The wake_up flag of this event may get set to 8979a844cf78f09953145200b4074d47589257a408cAravind Akella // WAKE_UP_SENSOR_EVENT_NEEDS_ACK if this is a wake_up event. 898eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu MostRecentEventLogger *circular_buf = mLastEventSeen.valueFor(handle); 899444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (circular_buf) { 900444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella sensors_event_t event; 901444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella memset(&event, 0, sizeof(event)); 902444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // It is unlikely that this buffer is empty as the sensor is already active. 903444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // One possible corner case may be two applications activating an on-change 904444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // sensor at the same time. 905444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if(circular_buf->populateLastEvent(&event)) { 906444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella event.sensor = handle; 907444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (event.version == sizeof(sensors_event_t)) { 908444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (isWakeUpSensorEvent(event) && !mWakeLockAcquired) { 909444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella setWakeLockAcquiredLocked(true); 910444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 911444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella connection->sendEvents(&event, 1, NULL); 912444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (!connection->needsWakeLock() && mWakeLockAcquired) { 913444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella checkWakeLockStateLocked(); 914444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 915444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 9169a844cf78f09953145200b4074d47589257a408cAravind Akella } 917f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 9187c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian } 919fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 920fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 9214342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 9224342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (connection->addSensor(handle)) { 9234342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh BatteryService::enableSensor(connection->getUid(), handle); 9244342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // the sensor was added (which means it wasn't already there) 9254342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // so, see if this connection becomes active 9264342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (mActiveConnections.indexOf(connection) < 0) { 9274342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh mActiveConnections.add(connection); 9284342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 9294342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } else { 9304342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh ALOGW("sensor %08x already enabled in connection %p (ignoring)", 9314342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh handle, connection.get()); 9324342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 9334342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 934724d91d778e71c8186399f4955de14b54812b3edAravind Akella nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs(); 935724d91d778e71c8186399f4955de14b54812b3edAravind Akella if (samplingPeriodNs < minDelayNs) { 936724d91d778e71c8186399f4955de14b54812b3edAravind Akella samplingPeriodNs = minDelayNs; 937724d91d778e71c8186399f4955de14b54812b3edAravind Akella } 938724d91d778e71c8186399f4955de14b54812b3edAravind Akella 9396c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d" 9406c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella "rate=%" PRId64 " timeout== %" PRId64"", 941724d91d778e71c8186399f4955de14b54812b3edAravind Akella handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs); 942724d91d778e71c8186399f4955de14b54812b3edAravind Akella 9434949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella status_t err = sensor->batch(connection.get(), handle, 0, samplingPeriodNs, 944724d91d778e71c8186399f4955de14b54812b3edAravind Akella maxBatchReportLatencyNs); 9456c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 94620483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // Call flush() before calling activate() on the sensor. Wait for a first 94720483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // flush complete event before sending events on this connection. Ignore 94820483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // one-shot sensors which don't support flush(). Ignore on-change sensors 94920483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // to maintain the on-change logic (any on-change events except the initial 95020483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // one should be trigger by a change in value). Also if this sensor isn't 95120483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // already active, don't call flush(). 95220483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu if (err == NO_ERROR && 95320483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu sensor->getSensor().getReportingMode() != AREPORTING_MODE_ONE_SHOT && 95420483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu sensor->getSensor().getReportingMode() != AREPORTING_MODE_ON_CHANGE && 9555466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella rec->getNumConnections() > 1) { 9565466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella connection->setFirstFlushPending(handle, true); 9574c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella status_t err_flush = sensor->flush(connection.get(), handle); 9585466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // Flush may return error if the underlying h/w sensor uses an older HAL. 9596c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella if (err_flush == NO_ERROR) { 9606c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella rec->addPendingFlushConnection(connection.get()); 9615466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella } else { 9625466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella connection->setFirstFlushPending(handle, false); 9634c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 9644c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 965724d91d778e71c8186399f4955de14b54812b3edAravind Akella 966724d91d778e71c8186399f4955de14b54812b3edAravind Akella if (err == NO_ERROR) { 967724d91d778e71c8186399f4955de14b54812b3edAravind Akella ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle); 968724d91d778e71c8186399f4955de14b54812b3edAravind Akella err = sensor->activate(connection.get(), true); 969724d91d778e71c8186399f4955de14b54812b3edAravind Akella } 970724d91d778e71c8186399f4955de14b54812b3edAravind Akella 9718a96955c8e14db40b16164236830fc9506a00872Aravind Akella if (err == NO_ERROR) { 9728a96955c8e14db40b16164236830fc9506a00872Aravind Akella connection->updateLooperRegistration(mLooper); 97318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella SensorRegistrationInfo ®_info = 97418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex); 97518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mSensorHandle = handle; 97618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mSamplingRateUs = samplingPeriodNs/1000; 97718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mMaxReportLatencyUs = maxBatchReportLatencyNs/1000; 97818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mActivated = true; 97918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mPackageName = connection->getPackageName(); 98018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella time_t rawtime = time(NULL); 98118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella struct tm * timeinfo = localtime(&rawtime); 98218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mHour = timeinfo->tm_hour; 98318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mMin = timeinfo->tm_min; 98418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mSec = timeinfo->tm_sec; 98518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mNextSensorRegIndex = (mNextSensorRegIndex + 1) % SENSOR_REGISTRATIONS_BUF_SIZE; 98656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 98756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 9884342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (err != NO_ERROR) { 989724d91d778e71c8186399f4955de14b54812b3edAravind Akella // batch/activate has failed, reset our state. 990ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian cleanupWithoutDisableLocked(connection, handle); 9914342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 992fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return err; 993fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 994fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 995fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::disable(const sp<SensorEventConnection>& connection, 996fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian int handle) 997fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 99850df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian if (mInitCheck != NO_ERROR) 99950df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian return mInitCheck; 100050df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian 1001ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian Mutex::Autolock _l(mLock); 1002ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian status_t err = cleanupWithoutDisableLocked(connection, handle); 10034342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (err == NO_ERROR) { 10044342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh SensorInterface* sensor = mSensorMap.valueFor(handle); 10054342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh err = sensor ? sensor->activate(connection.get(), false) : status_t(BAD_VALUE); 100618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella 100718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } 100818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella if (err == NO_ERROR) { 100918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella SensorRegistrationInfo ®_info = 101018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex); 101118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mActivated = false; 101218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mPackageName= connection->getPackageName(); 101318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mSensorHandle = handle; 101418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella time_t rawtime = time(NULL); 101518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella struct tm * timeinfo = localtime(&rawtime); 101618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mHour = timeinfo->tm_hour; 101718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mMin = timeinfo->tm_min; 101818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mSec = timeinfo->tm_sec; 101918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mNextSensorRegIndex = (mNextSensorRegIndex + 1) % SENSOR_REGISTRATIONS_BUF_SIZE; 10204342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 10214342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh return err; 10224342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh} 10234342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 1024ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisable( 1025ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian const sp<SensorEventConnection>& connection, int handle) { 1026fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian Mutex::Autolock _l(mLock); 1027ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian return cleanupWithoutDisableLocked(connection, handle); 1028ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian} 1029ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian 1030ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisableLocked( 1031ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian const sp<SensorEventConnection>& connection, int handle) { 1032fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian SensorRecord* rec = mActiveSensors.valueFor(handle); 1033fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian if (rec) { 1034fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian // see if this connection becomes inactive 1035787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian if (connection->removeSensor(handle)) { 1036787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian BatteryService::disableSensor(connection->getUid(), handle); 1037787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian } 1038fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian if (connection->hasAnySensor() == false) { 10398a96955c8e14db40b16164236830fc9506a00872Aravind Akella connection->updateLooperRegistration(mLooper); 1040fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian mActiveConnections.remove(connection); 1041fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 1042fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian // see if this sensor becomes inactive 1043fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian if (rec->removeConnection(connection)) { 1044fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian mActiveSensors.removeItem(handle); 1045f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian mActiveVirtualSensors.removeItem(handle); 1046fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian delete rec; 1047fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 10484342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh return NO_ERROR; 10497c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian } 10504342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh return BAD_VALUE; 1051fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 1052fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 10537c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianstatus_t SensorService::setEventRate(const sp<SensorEventConnection>& connection, 1054b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav int handle, nsecs_t ns, const String16& opPackageName) 1055fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 105650df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian if (mInitCheck != NO_ERROR) 105750df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian return mInitCheck; 105850df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian 1059ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian SensorInterface* sensor = mSensorMap.valueFor(handle); 1060ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian if (!sensor) 1061ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian return BAD_VALUE; 1062ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian 1063b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (!canAccessSensor(sensor->getSensor(), "Tried configuring", opPackageName)) { 1064700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return BAD_VALUE; 1065700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } 1066700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 10671cd700015318727d6d42236ab6274f1949fb08baMathias Agopian if (ns < 0) 10681cd700015318727d6d42236ab6274f1949fb08baMathias Agopian return BAD_VALUE; 10691cd700015318727d6d42236ab6274f1949fb08baMathias Agopian 107062569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs(); 107162569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian if (ns < minDelayNs) { 107262569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian ns = minDelayNs; 1073ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian } 1074ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian 1075f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian return sensor->setDelay(connection.get(), handle, ns); 1076fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 1077fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 1078b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslavstatus_t SensorService::flushSensor(const sp<SensorEventConnection>& connection, 1079b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav const String16& opPackageName) { 1080700180487ffec09d9df1657b018a7caadac24b75Aravind Akella if (mInitCheck != NO_ERROR) return mInitCheck; 10819e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella SensorDevice& dev(SensorDevice::getInstance()); 10829e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella const int halVersion = dev.getHalDeviceVersion(); 10839e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella status_t err(NO_ERROR); 10849e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella Mutex::Autolock _l(mLock); 10859e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // Loop through all sensors for this connection and call flush on each of them. 10869e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella for (size_t i = 0; i < connection->mSensorInfo.size(); ++i) { 10879e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella const int handle = connection->mSensorInfo.keyAt(i); 10889e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella SensorInterface* sensor = mSensorMap.valueFor(handle); 10899e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) { 10909e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella ALOGE("flush called on a one-shot sensor"); 10919e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella err = INVALID_OPERATION; 10929e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella continue; 10939e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } 10948493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (halVersion <= SENSORS_DEVICE_API_VERSION_1_0 || isVirtualSensor(handle)) { 10959e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // For older devices just increment pending flush count which will send a trivial 10969e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // flush complete event. 10978a96955c8e14db40b16164236830fc9506a00872Aravind Akella connection->incrementPendingFlushCount(handle); 10989e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } else { 1099b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (!canAccessSensor(sensor->getSensor(), "Tried flushing", opPackageName)) { 1100b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav err = INVALID_OPERATION; 1101b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav continue; 1102b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav } 11039e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella status_t err_flush = sensor->flush(connection.get(), handle); 11049e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella if (err_flush == NO_ERROR) { 11059e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella SensorRecord* rec = mActiveSensors.valueFor(handle); 11069e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella if (rec != NULL) rec->addPendingFlushConnection(connection); 11079e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } 11089e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella err = (err_flush != NO_ERROR) ? err_flush : err; 11099e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } 11106c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } 11119e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella return err; 1112700180487ffec09d9df1657b018a7caadac24b75Aravind Akella} 1113700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 1114b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslavbool SensorService::canAccessSensor(const Sensor& sensor, const char* operation, 1115b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav const String16& opPackageName) { 1116b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav const String8& requiredPermission = sensor.getRequiredPermission(); 1117700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 1118b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (requiredPermission.length() <= 0) { 1119700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return true; 1120b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav } 1121b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav 1122b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav bool hasPermission = false; 1123b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav 1124b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav // Runtime permissions can't use the cache as they may change. 1125b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (sensor.isRequiredPermissionRuntime()) { 1126b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav hasPermission = checkPermission(String16(requiredPermission), 1127b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav IPCThreadState::self()->getCallingPid(), IPCThreadState::self()->getCallingUid()); 1128700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } else { 1129b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav hasPermission = PermissionCache::checkCallingPermission(String16(requiredPermission)); 1130b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav } 1131b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav 1132b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (!hasPermission) { 1133b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav ALOGE("%s a sensor (%s) without holding its required permission: %s", 1134b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav operation, sensor.getName().string(), sensor.getRequiredPermission().string()); 1135700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return false; 1136700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } 1137b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav 1138b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav const int32_t opCode = sensor.getRequiredAppOp(); 1139b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (opCode >= 0) { 1140b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav AppOpsManager appOps; 1141b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (appOps.noteOp(opCode, IPCThreadState::self()->getCallingUid(), opPackageName) 1142b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav != AppOpsManager::MODE_ALLOWED) { 1143d4036b6b7f9609fe09efabdbfbb8c8f9428f76f7Andreas Gampe ALOGE("%s a sensor (%s) without enabled required app op: %d", 1144b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav operation, sensor.getName().string(), opCode); 1145b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav return false; 1146b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav } 1147b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav } 1148b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav 1149b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav return true; 1150700180487ffec09d9df1657b018a7caadac24b75Aravind Akella} 1151700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 11529a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockState() { 11539a844cf78f09953145200b4074d47589257a408cAravind Akella Mutex::Autolock _l(mLock); 11549a844cf78f09953145200b4074d47589257a408cAravind Akella checkWakeLockStateLocked(); 11559a844cf78f09953145200b4074d47589257a408cAravind Akella} 11569a844cf78f09953145200b4074d47589257a408cAravind Akella 11579a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockStateLocked() { 11589a844cf78f09953145200b4074d47589257a408cAravind Akella if (!mWakeLockAcquired) { 11599a844cf78f09953145200b4074d47589257a408cAravind Akella return; 11609a844cf78f09953145200b4074d47589257a408cAravind Akella } 11619a844cf78f09953145200b4074d47589257a408cAravind Akella bool releaseLock = true; 11629a844cf78f09953145200b4074d47589257a408cAravind Akella for (size_t i=0 ; i<mActiveConnections.size() ; i++) { 11639a844cf78f09953145200b4074d47589257a408cAravind Akella sp<SensorEventConnection> connection(mActiveConnections[i].promote()); 11649a844cf78f09953145200b4074d47589257a408cAravind Akella if (connection != 0) { 11659a844cf78f09953145200b4074d47589257a408cAravind Akella if (connection->needsWakeLock()) { 11669a844cf78f09953145200b4074d47589257a408cAravind Akella releaseLock = false; 11679a844cf78f09953145200b4074d47589257a408cAravind Akella break; 11689a844cf78f09953145200b4074d47589257a408cAravind Akella } 11699a844cf78f09953145200b4074d47589257a408cAravind Akella } 11709a844cf78f09953145200b4074d47589257a408cAravind Akella } 11719a844cf78f09953145200b4074d47589257a408cAravind Akella if (releaseLock) { 1172b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella setWakeLockAcquiredLocked(false); 1173b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 1174b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella} 1175b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella 1176b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::sendEventsFromCache(const sp<SensorEventConnection>& connection) { 1177b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella Mutex::Autolock _l(mLock); 1178b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella connection->writeToSocketFromCache(); 1179b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (connection->needsWakeLock()) { 1180b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella setWakeLockAcquiredLocked(true); 1181b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 1182b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella} 1183b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella 1184b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::populateActiveConnections( 1185b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella SortedVector< sp<SensorEventConnection> >* activeConnections) { 1186b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella Mutex::Autolock _l(mLock); 1187b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella for (size_t i=0 ; i < mActiveConnections.size(); ++i) { 1188b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella sp<SensorEventConnection> connection(mActiveConnections[i].promote()); 1189b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (connection != 0) { 1190b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella activeConnections->add(connection); 1191b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 11929a844cf78f09953145200b4074d47589257a408cAravind Akella } 11939a844cf78f09953145200b4074d47589257a408cAravind Akella} 11946c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 11954949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akellabool SensorService::isWhiteListedPackage(const String8& packageName) { 1196841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella return (packageName.contains(mWhiteListedPackage.string())); 11974949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella} 11984949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella 1199444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akellaint SensorService::getNumEventsForSensorType(int sensor_event_type) { 1200444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella switch (sensor_event_type) { 1201444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella case SENSOR_TYPE_ROTATION_VECTOR: 1202444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR: 1203444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella return 5; 1204444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella 1205444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED: 1206444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED: 1207444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella return 6; 1208444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella 1209444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella case SENSOR_TYPE_GAME_ROTATION_VECTOR: 1210444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella return 4; 1211444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella 1212444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella case SENSOR_TYPE_SIGNIFICANT_MOTION: 1213444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella case SENSOR_TYPE_STEP_DETECTOR: 1214444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella case SENSOR_TYPE_STEP_COUNTER: 1215444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella return 1; 1216444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella 1217444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella default: 1218444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella return 3; 1219444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 1220444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella} 1221444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella 1222fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}; // namespace android 1223fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 1224