SensorService.cpp revision bfac17eed90d410de51413ef2484f79fb0e241e2
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 2953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <openssl/digest.h> 3053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <openssl/hmac.h> 3153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <openssl/rand.h> 3253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 33787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian#include "BatteryService.h" 34984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "CorrectedGyroSensor.h" 35f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "GravitySensor.h" 36f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "LinearAccelerationSensor.h" 37984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "OrientationSensor.h" 38f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "RotationVectorSensor.h" 39984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "SensorFusion.h" 40755c451c7861a029e26e5f16e319b629169e656dPeng Xu#include "SensorInterface.h" 41eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu 42984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "SensorService.h" 43eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include "SensorEventAckReceiver.h" 446a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu#include "SensorEventConnection.h" 45eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include "SensorRecord.h" 46eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include "SensorRegistrationInfo.h" 47eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu 48eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <inttypes.h> 49eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <math.h> 50eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <stdint.h> 51eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <sys/socket.h> 5253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <sys/stat.h> 5353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <sys/types.h> 5453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <unistd.h> 55fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 56fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopiannamespace android { 57fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// --------------------------------------------------------------------------- 58fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 593301542828febc768e1df42892cfac4992c35474Mathias Agopian/* 603301542828febc768e1df42892cfac4992c35474Mathias Agopian * Notes: 613301542828febc768e1df42892cfac4992c35474Mathias Agopian * 623301542828febc768e1df42892cfac4992c35474Mathias Agopian * - what about a gyro-corrected magnetic-field sensor? 633301542828febc768e1df42892cfac4992c35474Mathias Agopian * - run mag sensor from time to time to force calibration 643301542828febc768e1df42892cfac4992c35474Mathias Agopian * - gravity sensor length is wrong (=> drift in linear-acc sensor) 653301542828febc768e1df42892cfac4992c35474Mathias Agopian * 663301542828febc768e1df42892cfac4992c35474Mathias Agopian */ 673301542828febc768e1df42892cfac4992c35474Mathias Agopian 688ef3c89eb2030395f8a342bd16dbb344957ab275Aravind Akellaconst char* SensorService::WAKE_LOCK_NAME = "SensorService_wakelock"; 6953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiseruint8_t SensorService::sHmacGlobalKey[128] = {}; 7053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiserbool SensorService::sHmacGlobalKeyIsValid = false; 7153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 7253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#define SENSOR_SERVICE_DIR "/data/system/sensor_service" 7353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#define SENSOR_SERVICE_HMAC_KEY_FILE SENSOR_SERVICE_DIR "/hmac_key" 7453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 75a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella// Permissions. 76a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatic const String16 sDump("android.permission.DUMP"); 774342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 78fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorService() 798a96955c8e14db40b16164236830fc9506a00872Aravind Akella : mInitCheck(NO_INIT), mSocketBufferSize(SOCKET_BUFFER_SIZE_NON_BATCHED), 8047e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu mWakeLockAcquired(false) { 81fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 82fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 8353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiserbool SensorService::initializeHmacKey() { 8453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser int fd = open(SENSOR_SERVICE_HMAC_KEY_FILE, O_RDONLY|O_CLOEXEC); 8553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (fd != -1) { 8653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser int result = read(fd, sHmacGlobalKey, sizeof(sHmacGlobalKey)); 8753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser close(fd); 8853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (result == sizeof(sHmacGlobalKey)) { 8953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return true; 9053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 9153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser ALOGW("Unable to read HMAC key; generating new one."); 9253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 9353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 9453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (RAND_bytes(sHmacGlobalKey, sizeof(sHmacGlobalKey)) == -1) { 9553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser ALOGW("Can't generate HMAC key; dynamic sensor getId() will be wrong."); 9653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return false; 9753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 9853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 9953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // We need to make sure this is only readable to us. 10053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser bool wroteKey = false; 10153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser mkdir(SENSOR_SERVICE_DIR, S_IRWXU); 10253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser fd = open(SENSOR_SERVICE_HMAC_KEY_FILE, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, 10353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser S_IRUSR|S_IWUSR); 10453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (fd != -1) { 10553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser int result = write(fd, sHmacGlobalKey, sizeof(sHmacGlobalKey)); 10653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser close(fd); 10753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser wroteKey = (result == sizeof(sHmacGlobalKey)); 10853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 10953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (wroteKey) { 11053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser ALOGI("Generated new HMAC key."); 11153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } else { 11253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser ALOGW("Unable to write HMAC key; dynamic sensor getId() will change " 11353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser "after reboot."); 11453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 11553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Even if we failed to write the key we return true, because we did 11653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // initialize the HMAC key. 11753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return true; 11853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser} 11953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 12047e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xuvoid SensorService::onFirstRef() { 121a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block ALOGD("nuSensorService starting..."); 122f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian SensorDevice& dev(SensorDevice::getInstance()); 123fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 12453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser sHmacGlobalKeyIsValid = initializeHmacKey(); 12553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 126f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian if (dev.initCheck() == NO_ERROR) { 127f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sensor_t const* list; 1287b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian ssize_t count = dev.getSensorList(&list); 1297b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian if (count > 0) { 1307b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian ssize_t orientationIndex = -1; 131f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella bool hasGyro = false, hasAccel = false, hasMag = false; 1327b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian uint32_t virtualSensorsNeeds = 1337b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian (1<<SENSOR_TYPE_GRAVITY) | 1347b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian (1<<SENSOR_TYPE_LINEAR_ACCELERATION) | 135f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu (1<<SENSOR_TYPE_ROTATION_VECTOR) | 136f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR) | 137f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR); 1387b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian 1397b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian for (ssize_t i=0 ; i<count ; i++) { 140f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu bool useThisSensor=true; 141f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu 1427b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian switch (list[i].type) { 143f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella case SENSOR_TYPE_ACCELEROMETER: 144f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella hasAccel = true; 145f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella break; 146f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella case SENSOR_TYPE_MAGNETIC_FIELD: 147f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella hasMag = true; 148f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella break; 1497b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian case SENSOR_TYPE_ORIENTATION: 1507b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian orientationIndex = i; 1517b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian break; 1527b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian case SENSOR_TYPE_GYROSCOPE: 1530319306670b0344da99efa606b6f172dde575a39Mathias Agopian case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED: 1547b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian hasGyro = true; 1557b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian break; 1567b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian case SENSOR_TYPE_GRAVITY: 1577b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian case SENSOR_TYPE_LINEAR_ACCELERATION: 1587b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian case SENSOR_TYPE_ROTATION_VECTOR: 159f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR: 160f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu case SENSOR_TYPE_GAME_ROTATION_VECTOR: 161f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu if (IGNORE_HARDWARE_FUSION) { 162f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu useThisSensor = false; 163f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu } else { 164f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu virtualSensorsNeeds &= ~(1<<list[i].type); 165f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu } 1667b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian break; 1677b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian } 168f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu if (useThisSensor) { 169f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu registerSensor( new HardwareSensor(list[i]) ); 170f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu } 17150df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian } 172fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 1737b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian // it's safe to instantiate the SensorFusion object here 1747b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian // (it wants to be instantiated after h/w sensors have been 1757b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian // registered) 176d4036b6b7f9609fe09efabdbfbb8c8f9428f76f7Andreas Gampe SensorFusion::getInstance(); 1777b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian 178f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella if (hasGyro && hasAccel && hasMag) { 1790319306670b0344da99efa606b6f172dde575a39Mathias Agopian // Add Android virtual sensors if they're not already 1800319306670b0344da99efa606b6f172dde575a39Mathias Agopian // available in the HAL 1810cc8f809924706c7d683da30605f432635dd5bb6Peng Xu bool needRotationVector = 1820cc8f809924706c7d683da30605f432635dd5bb6Peng Xu (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) != 0; 1837b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian 1840cc8f809924706c7d683da30605f432635dd5bb6Peng Xu registerSensor(new RotationVectorSensor(), !needRotationVector, true); 1850cc8f809924706c7d683da30605f432635dd5bb6Peng Xu registerSensor(new OrientationSensor(), !needRotationVector, true); 186f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 1870cc8f809924706c7d683da30605f432635dd5bb6Peng Xu bool needLinearAcceleration = 1880cc8f809924706c7d683da30605f432635dd5bb6Peng Xu (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) != 0; 1890319306670b0344da99efa606b6f172dde575a39Mathias Agopian 1900cc8f809924706c7d683da30605f432635dd5bb6Peng Xu registerSensor(new LinearAccelerationSensor(list, count), 1910cc8f809924706c7d683da30605f432635dd5bb6Peng Xu !needLinearAcceleration, true); 192f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu 1930cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // virtual debugging sensors are not for user 194755c451c7861a029e26e5f16e319b629169e656dPeng Xu registerSensor( new CorrectedGyroSensor(list, count), true, true); 195755c451c7861a029e26e5f16e319b629169e656dPeng Xu registerSensor( new GyroDriftSensor(), true, true); 196010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian } 197010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian 198f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu if (hasAccel && hasGyro) { 1990cc8f809924706c7d683da30605f432635dd5bb6Peng Xu bool needGravitySensor = (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) != 0; 2000cc8f809924706c7d683da30605f432635dd5bb6Peng Xu registerSensor(new GravitySensor(list, count), !needGravitySensor, true); 201f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu 2020cc8f809924706c7d683da30605f432635dd5bb6Peng Xu bool needGameRotationVector = 2030cc8f809924706c7d683da30605f432635dd5bb6Peng Xu (virtualSensorsNeeds & (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR)) != 0; 2040cc8f809924706c7d683da30605f432635dd5bb6Peng Xu registerSensor(new GameRotationVectorSensor(), !needGameRotationVector, true); 205f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu } 206f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu 207f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu if (hasAccel && hasMag) { 2080cc8f809924706c7d683da30605f432635dd5bb6Peng Xu bool needGeoMagRotationVector = 2090cc8f809924706c7d683da30605f432635dd5bb6Peng Xu (virtualSensorsNeeds & (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR)) != 0; 2100cc8f809924706c7d683da30605f432635dd5bb6Peng Xu registerSensor(new GeoMagRotationVectorSensor(), !needGeoMagRotationVector, true); 211f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu } 212f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu 2135466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // Check if the device really supports batching by looking at the FIFO event 2145466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // counts for each sensor. 2155466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella bool batchingSupported = false; 2160cc8f809924706c7d683da30605f432635dd5bb6Peng Xu mSensors.forEachSensor( 2170cc8f809924706c7d683da30605f432635dd5bb6Peng Xu [&batchingSupported] (const Sensor& s) -> bool { 2180cc8f809924706c7d683da30605f432635dd5bb6Peng Xu if (s.getFifoMaxEventCount() > 0) { 2190cc8f809924706c7d683da30605f432635dd5bb6Peng Xu batchingSupported = true; 2200cc8f809924706c7d683da30605f432635dd5bb6Peng Xu } 2210cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return !batchingSupported; 2220cc8f809924706c7d683da30605f432635dd5bb6Peng Xu }); 2235466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella 2245466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella if (batchingSupported) { 2255466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // Increase socket buffer size to a max of 100 KB for batching capabilities. 2265466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella mSocketBufferSize = MAX_SOCKET_BUFFER_SIZE_BATCHED; 2275466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella } else { 2285466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella mSocketBufferSize = SOCKET_BUFFER_SIZE_NON_BATCHED; 2295466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella } 2305466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella 2315466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // Compare the socketBufferSize value against the system limits and limit 2325466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // it to maxSystemSocketBufferSize if necessary. 2334c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella FILE *fp = fopen("/proc/sys/net/core/wmem_max", "r"); 2344c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella char line[128]; 2354c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella if (fp != NULL && fgets(line, sizeof(line), fp) != NULL) { 2364c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella line[sizeof(line) - 1] = '\0'; 2375466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella size_t maxSystemSocketBufferSize; 2385466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella sscanf(line, "%zu", &maxSystemSocketBufferSize); 2395466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella if (mSocketBufferSize > maxSystemSocketBufferSize) { 2405466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella mSocketBufferSize = maxSystemSocketBufferSize; 2414c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 2424c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 2434c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella if (fp) { 2444c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella fclose(fp); 2454c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 2464c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella 2479a844cf78f09953145200b4074d47589257a408cAravind Akella mWakeLockAcquired = false; 24856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella mLooper = new Looper(false); 2498493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT; 2508493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mSensorEventBuffer = new sensors_event_t[minBufferSize]; 2518493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mSensorEventScratch = new sensors_event_t[minBufferSize]; 2528493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize]; 253a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella mCurrentOperatingMode = NORMAL; 2547830ef3dd0ff3749d974c2dd85a8fa59dc47aecaAravind Akella 25518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mNextSensorRegIndex = 0; 25618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella for (int i = 0; i < SENSOR_REGISTRATIONS_BUF_SIZE; ++i) { 25718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mLastNSensorRegistrations.push(); 25818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } 25918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella 26018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mInitCheck = NO_ERROR; 261b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mAckReceiver = new SensorEventAckReceiver(this); 262b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY); 2637830ef3dd0ff3749d974c2dd85a8fa59dc47aecaAravind Akella run("SensorService", PRIORITY_URGENT_DISPLAY); 2647b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian } 265fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 266fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 267fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 2680cc8f809924706c7d683da30605f432635dd5bb6Peng Xuconst Sensor& SensorService::registerSensor(SensorInterface* s, bool isDebug, bool isVirtual) { 2690cc8f809924706c7d683da30605f432635dd5bb6Peng Xu int handle = s->getSensor().getHandle(); 2706a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu int type = s->getSensor().getType(); 2710cc8f809924706c7d683da30605f432635dd5bb6Peng Xu if (mSensors.add(handle, s, isDebug, isVirtual)){ 2726a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mRecentEvent.emplace(handle, new RecentEventLogger(type)); 2730cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return s->getSensor(); 2740cc8f809924706c7d683da30605f432635dd5bb6Peng Xu } else { 2750cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return mSensors.getNonSensor(); 2760cc8f809924706c7d683da30605f432635dd5bb6Peng Xu } 277f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian} 278f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 2796a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xuconst Sensor& SensorService::registerDynamicSensorLocked(SensorInterface* s, bool isDebug) { 2800cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return registerSensor(s, isDebug); 2812576cb63b3fe1592f54816625036566b9eb0793aPeng Xu} 2822576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 2836a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xubool SensorService::unregisterDynamicSensorLocked(int handle) { 2840cc8f809924706c7d683da30605f432635dd5bb6Peng Xu bool ret = mSensors.remove(handle); 2856a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 2866a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu const auto i = mRecentEvent.find(handle); 2876a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu if (i != mRecentEvent.end()) { 2886a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu delete i->second; 2896a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mRecentEvent.erase(i); 2902576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 2910cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return ret; 292f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian} 293f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 2940cc8f809924706c7d683da30605f432635dd5bb6Peng Xuconst Sensor& SensorService::registerVirtualSensor(SensorInterface* s, bool isDebug) { 2950cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return registerSensor(s, isDebug, true); 29647e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu} 29747e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu 29847e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng XuSensorService::~SensorService() { 2996a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu for (auto && entry : mRecentEvent) { 3006a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu delete entry.second; 3016a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu } 302fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 303fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 30447e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xustatus_t SensorService::dump(int fd, const Vector<String16>& args) { 305fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian String8 result; 3061cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian if (!PermissionCache::checkCallingPermission(sDump)) { 307eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu result.appendFormat("Permission Denial: can't dump SensorService from pid=%d, uid=%d\n", 308fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian IPCThreadState::self()->getCallingPid(), 309fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian IPCThreadState::self()->getCallingUid()); 310444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } else { 311841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (args.size() > 2) { 3124949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella return INVALID_OPERATION; 3134949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella } 3144949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella Mutex::Autolock _l(mLock); 3154949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella SensorDevice& dev(SensorDevice::getInstance()); 316841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (args.size() == 2 && args[0] == String16("restrict")) { 317444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // If already in restricted mode. Ignore. 318444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (mCurrentOperatingMode == RESTRICTED) { 319444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella return status_t(NO_ERROR); 320444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 321444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // If in any mode other than normal, ignore. 322444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (mCurrentOperatingMode != NORMAL) { 323444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella return INVALID_OPERATION; 324444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 325a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella mCurrentOperatingMode = RESTRICTED; 3264949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella dev.disableAllSensors(); 3274949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella // Clear all pending flush connections for all active sensors. If one of the active 3284949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella // connections has called flush() and the underlying sensor has been disabled before a 3294949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella // flush complete event is returned, we need to remove the connection from this queue. 3304949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella for (size_t i=0 ; i< mActiveSensors.size(); ++i) { 3314949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella mActiveSensors.valueAt(i)->clearAllPendingFlushConnections(); 3324949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella } 333841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella mWhiteListedPackage.setTo(String8(args[1])); 334444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella return status_t(NO_ERROR); 335444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } else if (args.size() == 1 && args[0] == String16("enable")) { 336444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // If currently in restricted mode, reset back to NORMAL mode else ignore. 337444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (mCurrentOperatingMode == RESTRICTED) { 338444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella mCurrentOperatingMode = NORMAL; 339444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella dev.enableAllSensors(); 3406c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } 341841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (mCurrentOperatingMode == DATA_INJECTION) { 342841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella resetToNormalModeLocked(); 343841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } 344841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella mWhiteListedPackage.clear(); 345444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella return status_t(NO_ERROR); 346841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } else if (args.size() == 2 && args[0] == String16("data_injection")) { 347841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (mCurrentOperatingMode == NORMAL) { 348841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella dev.disableAllSensors(); 349841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella status_t err = dev.setMode(DATA_INJECTION); 350841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (err == NO_ERROR) { 351841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella mCurrentOperatingMode = DATA_INJECTION; 352841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } else { 353841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella // Re-enable sensors. 354841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella dev.enableAllSensors(); 355841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } 356841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella mWhiteListedPackage.setTo(String8(args[1])); 357841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella return NO_ERROR; 358841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } else if (mCurrentOperatingMode == DATA_INJECTION) { 359841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella // Already in DATA_INJECTION mode. Treat this as a no_op. 360841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella return NO_ERROR; 361841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } else { 362841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella // Transition to data injection mode supported only from NORMAL mode. 363841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella return INVALID_OPERATION; 364841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } 3650cc8f809924706c7d683da30605f432635dd5bb6Peng Xu } else if (!mSensors.hasAnySensor()) { 366ee155cadb23e84542cbf445c2aac89ae63df4cc7Aravind Akella result.append("No Sensors on the device\n"); 367444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } else { 368444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // Default dump the sensor list and debugging information. 3690cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // 3706a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu result.append("Sensor Device:\n"); 3716a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu result.append(SensorDevice::getInstance().dump().c_str()); 3726a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 3736a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu result.append("Sensor List:\n"); 3740cc8f809924706c7d683da30605f432635dd5bb6Peng Xu result.append(mSensors.dump().c_str()); 3756c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 3766a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu result.append("Fusion States:\n"); 377444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella SensorFusion::getInstance().dump(result); 378444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella 3790cc8f809924706c7d683da30605f432635dd5bb6Peng Xu result.append("Recent Sensor events:\n"); 3806a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu for (auto&& i : mRecentEvent) { 3816a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu sp<SensorInterface> s = mSensors.getInterface(i.first); 3826a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu if (!i.second->isEmpty() && 3836a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu s->getSensor().getRequiredPermission().isEmpty()) { 3846a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu // if there is events and sensor does not need special permission. 3856a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu result.appendFormat("%s: ", s->getSensor().getName().string()); 3866a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu result.append(i.second->dump().c_str()); 3876a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu } 3886a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu } 3890cc8f809924706c7d683da30605f432635dd5bb6Peng Xu 390444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.append("Active sensors:\n"); 391444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella for (size_t i=0 ; i<mActiveSensors.size() ; i++) { 392444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella int handle = mActiveSensors.keyAt(i); 393444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat("%s (handle=0x%08x, connections=%zu)\n", 394444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella getSensorName(handle).string(), 395444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella handle, 396444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella mActiveSensors.valueAt(i)->getNumConnections()); 397ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian } 3984c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella 399d4036b6b7f9609fe09efabdbfbb8c8f9428f76f7Andreas Gampe result.appendFormat("Socket Buffer size = %zd events\n", 400444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella mSocketBufferSize/sizeof(sensors_event_t)); 40118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella result.appendFormat("WakeLock Status: %s \n", mWakeLockAcquired ? "acquired" : 40218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella "not held"); 403444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat("Mode :"); 404444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella switch(mCurrentOperatingMode) { 405444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella case NORMAL: 406444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat(" NORMAL\n"); 407444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella break; 408444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella case RESTRICTED: 409841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella result.appendFormat(" RESTRICTED : %s\n", mWhiteListedPackage.string()); 410444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella break; 411444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella case DATA_INJECTION: 412841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella result.appendFormat(" DATA_INJECTION : %s\n", mWhiteListedPackage.string()); 413444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 414444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat("%zd active connections\n", mActiveConnections.size()); 4154c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella 416444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella for (size_t i=0 ; i < mActiveConnections.size() ; i++) { 417444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella sp<SensorEventConnection> connection(mActiveConnections[i].promote()); 418444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (connection != 0) { 419444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat("Connection Number: %zu \n", i); 420444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella connection->dump(result); 421444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 4224c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 42318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella 42418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella result.appendFormat("Previous Registrations:\n"); 42518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella // Log in the reverse chronological order. 42618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella int currentIndex = (mNextSensorRegIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) % 42718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella SENSOR_REGISTRATIONS_BUF_SIZE; 42818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella const int startIndex = currentIndex; 42918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella do { 43018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella const SensorRegistrationInfo& reg_info = mLastNSensorRegistrations[currentIndex]; 43118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella if (SensorRegistrationInfo::isSentinel(reg_info)) { 43218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella // Ignore sentinel, proceed to next item. 43318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella currentIndex = (currentIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) % 43418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella SENSOR_REGISTRATIONS_BUF_SIZE; 43518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella continue; 43618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } 43718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella if (reg_info.mActivated) { 43818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella result.appendFormat("%02d:%02d:%02d activated package=%s handle=0x%08x " 43918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella "samplingRate=%dus maxReportLatency=%dus\n", 44018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mHour, reg_info.mMin, reg_info.mSec, 44118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mPackageName.string(), reg_info.mSensorHandle, 44218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mSamplingRateUs, reg_info.mMaxReportLatencyUs); 44318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } else { 44418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella result.appendFormat("%02d:%02d:%02d de-activated package=%s handle=0x%08x\n", 44518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mHour, reg_info.mMin, reg_info.mSec, 44618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mPackageName.string(), reg_info.mSensorHandle); 44718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } 44818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella currentIndex = (currentIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) % 44918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella SENSOR_REGISTRATIONS_BUF_SIZE; 45018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } while(startIndex != currentIndex); 4514c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 452fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 453fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian write(fd, result.string(), result.size()); 454fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return NO_ERROR; 455fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 456fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 4570cc8f809924706c7d683da30605f432635dd5bb6Peng Xu//TODO: move to SensorEventConnection later 4589a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::cleanupAutoDisabledSensorLocked(const sp<SensorEventConnection>& connection, 4594342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh sensors_event_t const* buffer, const int count) { 4604342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh for (int i=0 ; i<count ; i++) { 4614342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh int handle = buffer[i].sensor; 4628493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (buffer[i].type == SENSOR_TYPE_META_DATA) { 4638493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella handle = buffer[i].meta_data.sensor; 4648493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } 4650e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella if (connection->hasSensor(handle)) { 466755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> si = getSensorInterfaceFromHandle(handle); 4670e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella // If this buffer has an event from a one_shot sensor and this connection is registered 4680e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella // for this particular one_shot sensor, try cleaning up the connection. 469755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (si != nullptr && 4700cc8f809924706c7d683da30605f432635dd5bb6Peng Xu si->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) { 4710cc8f809924706c7d683da30605f432635dd5bb6Peng Xu si->autoDisable(connection.get(), handle); 4729a844cf78f09953145200b4074d47589257a408cAravind Akella cleanupWithoutDisableLocked(connection, handle); 4734342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 474a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella 4754342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 476a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella } 4774342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh} 4784342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 47947e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xubool SensorService::threadLoop() { 480a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block ALOGD("nuSensorService thread starting..."); 481fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 482eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // each virtual sensor could generate an event per "real" event, that's why we need to size 483eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT. in practice, this is too 484eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // aggressive, but guaranteed to be enough. 4850cc8f809924706c7d683da30605f432635dd5bb6Peng Xu const size_t vcount = mSensors.getVirtualSensors().size(); 48690ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT; 4870cc8f809924706c7d683da30605f432635dd5bb6Peng Xu const size_t numEventMax = minBufferSize / (1 + vcount); 48890ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian 489f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian SensorDevice& device(SensorDevice::getInstance()); 490fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 4914342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh const int halVersion = device.getHalDeviceVersion(); 492fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian do { 4938493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella ssize_t count = device.poll(mSensorEventBuffer, numEventMax); 4948493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (count < 0) { 495f5a1230d322c14c42331d0a1536b50c87742973bSteve Block ALOGE("sensor poll failed (%s)", strerror(-count)); 496fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian break; 497fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 49856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 49956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // Reset sensors_event_t.flags to zero for all events in the buffer. 50056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella for (int i = 0; i < count; i++) { 5018493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mSensorEventBuffer[i].flags = 0; 50256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 503e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella 504eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // Make a copy of the connection vector as some connections may be removed during the course 505eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // of this loop (especially when one-shot sensor events are present in the sensor_event 506eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // buffer). Promote all connections to StrongPointers before the lock is acquired. If the 507eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // destructor of the sp gets called when the lock is acquired, it may result in a deadlock 508eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // as ~SensorEventConnection() needs to acquire mLock again for cleanup. So copy all the 509eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // strongPointers to a vector before the lock is acquired. 510e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella SortedVector< sp<SensorEventConnection> > activeConnections; 511b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella populateActiveConnections(&activeConnections); 512eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu 5139a844cf78f09953145200b4074d47589257a408cAravind Akella Mutex::Autolock _l(mLock); 5149a844cf78f09953145200b4074d47589257a408cAravind Akella // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The 5159a844cf78f09953145200b4074d47589257a408cAravind Akella // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock, 5169a844cf78f09953145200b4074d47589257a408cAravind Akella // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should 5179a844cf78f09953145200b4074d47589257a408cAravind Akella // not be interleaved with decrementing SensorEventConnection::mWakeLockRefCount and 5189a844cf78f09953145200b4074d47589257a408cAravind Akella // releasing the wakelock. 5199a844cf78f09953145200b4074d47589257a408cAravind Akella bool bufferHasWakeUpEvent = false; 5204342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh for (int i = 0; i < count; i++) { 5218493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (isWakeUpSensorEvent(mSensorEventBuffer[i])) { 5229a844cf78f09953145200b4074d47589257a408cAravind Akella bufferHasWakeUpEvent = true; 5239a844cf78f09953145200b4074d47589257a408cAravind Akella break; 5244342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 5254342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 5264342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 5279a844cf78f09953145200b4074d47589257a408cAravind Akella if (bufferHasWakeUpEvent && !mWakeLockAcquired) { 528b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella setWakeLockAcquiredLocked(true); 5299a844cf78f09953145200b4074d47589257a408cAravind Akella } 5308493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella recordLastValueLocked(mSensorEventBuffer, count); 53194e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian 532f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian // handle virtual sensors 533f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian if (count && vcount) { 5348493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella sensors_event_t const * const event = mSensorEventBuffer; 535755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (!mActiveVirtualSensors.empty()) { 536f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian size_t k = 0; 537984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian SensorFusion& fusion(SensorFusion::getInstance()); 538984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian if (fusion.isEnabled()) { 539984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t i=0 ; i<size_t(count) ; i++) { 540984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian fusion.process(event[i]); 541984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 542984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 543d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) { 544755c451c7861a029e26e5f16e319b629169e656dPeng Xu for (int handle : mActiveVirtualSensors) { 545d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian if (count + k >= minBufferSize) { 546d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian ALOGE("buffer too small to hold all events: " 547db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn "count=%zd, k=%zu, size=%zu", 548d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian count, k, minBufferSize); 549d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian break; 550d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian } 551f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sensors_event_t out; 552755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> si = mSensors.getInterface(handle); 553755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (si == nullptr) { 554755c451c7861a029e26e5f16e319b629169e656dPeng Xu ALOGE("handle %d is not an valid virtual sensor", handle); 555755c451c7861a029e26e5f16e319b629169e656dPeng Xu continue; 556755c451c7861a029e26e5f16e319b629169e656dPeng Xu } 557755c451c7861a029e26e5f16e319b629169e656dPeng Xu 558d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian if (si->process(&out, event[i])) { 5598493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mSensorEventBuffer[count + k] = out; 560f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian k++; 561f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 562f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 563f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 564f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian if (k) { 565f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian // record the last synthesized values 5668493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella recordLastValueLocked(&mSensorEventBuffer[count], k); 567f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian count += k; 568f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian // sort the buffer by time-stamps 5698493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella sortEventBuffer(mSensorEventBuffer, count); 570f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 571f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 572f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 573f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 5744342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // handle backward compatibility for RotationVector sensor 5754342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) { 5764342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh for (int i = 0; i < count; i++) { 5778493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (mSensorEventBuffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) { 5784342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // All the 4 components of the quaternion should be available 5794342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // No heading accuracy. Set it to -1 5808493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mSensorEventBuffer[i].data[4] = -1; 5818493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } 5828493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } 5838493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } 5848493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella 5858493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella for (int i = 0; i < count; ++i) { 5860cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // Map flush_complete_events in the buffer to SensorEventConnections which called flush 5870cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // on the hardware sensor. mapFlushEventsToConnections[i] will be the 5880cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // SensorEventConnection mapped to the corresponding flush_complete_event in 5890cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // mSensorEventBuffer[i] if such a mapping exists (NULL otherwise). 5908493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mMapFlushEventsToConnections[i] = NULL; 5918493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (mSensorEventBuffer[i].type == SENSOR_TYPE_META_DATA) { 5928493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella const int sensor_handle = mSensorEventBuffer[i].meta_data.sensor; 5938493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella SensorRecord* rec = mActiveSensors.valueFor(sensor_handle); 5948493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (rec != NULL) { 5958493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mMapFlushEventsToConnections[i] = rec->getFirstPendingFlushConnection(); 5968493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella rec->removeFirstPendingFlushConnection(); 5974342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 5984342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 5992576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 6002576cb63b3fe1592f54816625036566b9eb0793aPeng Xu // handle dynamic sensor meta events, process registration and unregistration of dynamic 6012576cb63b3fe1592f54816625036566b9eb0793aPeng Xu // sensor based on content of event. 6022576cb63b3fe1592f54816625036566b9eb0793aPeng Xu if (mSensorEventBuffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META) { 6032576cb63b3fe1592f54816625036566b9eb0793aPeng Xu if (mSensorEventBuffer[i].dynamic_sensor_meta.connected) { 6042576cb63b3fe1592f54816625036566b9eb0793aPeng Xu int handle = mSensorEventBuffer[i].dynamic_sensor_meta.handle; 6052576cb63b3fe1592f54816625036566b9eb0793aPeng Xu const sensor_t& dynamicSensor = 6062576cb63b3fe1592f54816625036566b9eb0793aPeng Xu *(mSensorEventBuffer[i].dynamic_sensor_meta.sensor); 6072576cb63b3fe1592f54816625036566b9eb0793aPeng Xu ALOGI("Dynamic sensor handle 0x%x connected, type %d, name %s", 6082576cb63b3fe1592f54816625036566b9eb0793aPeng Xu handle, dynamicSensor.type, dynamicSensor.name); 6092576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 6100cc8f809924706c7d683da30605f432635dd5bb6Peng Xu if (mSensors.isNewHandle(handle)) { 6116a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu const auto& uuid = mSensorEventBuffer[i].dynamic_sensor_meta.uuid; 61247e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu sensor_t s = dynamicSensor; 61347e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu // make sure the dynamic sensor flag is set 61447e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu s.flags |= DYNAMIC_SENSOR_MASK; 61547e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu // force the handle to be consistent 61647e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu s.handle = handle; 6176a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 6186a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu SensorInterface *si = new HardwareSensor(s, uuid); 61947e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu 6200cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // This will release hold on dynamic sensor meta, so it should be called 6210cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // after Sensor object is created. 62247e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu device.handleDynamicSensorConnection(handle, true /*connected*/); 6236a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu registerDynamicSensorLocked(si); 62447e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu } else { 62547e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu ALOGE("Handle %d has been used, cannot use again before reboot.", handle); 62647e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu } 6272576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } else { 6282576cb63b3fe1592f54816625036566b9eb0793aPeng Xu int handle = mSensorEventBuffer[i].dynamic_sensor_meta.handle; 6292576cb63b3fe1592f54816625036566b9eb0793aPeng Xu ALOGI("Dynamic sensor handle 0x%x disconnected", handle); 6302576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 6312576cb63b3fe1592f54816625036566b9eb0793aPeng Xu device.handleDynamicSensorConnection(handle, false /*connected*/); 6326a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu if (!unregisterDynamicSensorLocked(handle)) { 6332576cb63b3fe1592f54816625036566b9eb0793aPeng Xu ALOGE("Dynamic sensor release error."); 6342576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 6352576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 6362576cb63b3fe1592f54816625036566b9eb0793aPeng Xu size_t numConnections = activeConnections.size(); 6372576cb63b3fe1592f54816625036566b9eb0793aPeng Xu for (size_t i=0 ; i < numConnections; ++i) { 6382576cb63b3fe1592f54816625036566b9eb0793aPeng Xu if (activeConnections[i] != NULL) { 6392576cb63b3fe1592f54816625036566b9eb0793aPeng Xu activeConnections[i]->removeSensor(handle); 6402576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 6412576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 6422576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 6432576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 6444342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 6454342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 6462576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 6479a844cf78f09953145200b4074d47589257a408cAravind Akella // Send our events to clients. Check the state of wake lock for each client and release the 6489a844cf78f09953145200b4074d47589257a408cAravind Akella // lock if none of the clients need it. 6499a844cf78f09953145200b4074d47589257a408cAravind Akella bool needsWakeLock = false; 6508493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella size_t numConnections = activeConnections.size(); 6518493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella for (size_t i=0 ; i < numConnections; ++i) { 652e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella if (activeConnections[i] != 0) { 653e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch, 6548493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mMapFlushEventsToConnections); 655e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella needsWakeLock |= activeConnections[i]->needsWakeLock(); 6568493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella // If the connection has one-shot sensors, it may be cleaned up after first trigger. 6578493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella // Early check for one-shot sensors. 658e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella if (activeConnections[i]->hasOneShotSensors()) { 659e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer, 660e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella count); 6618493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } 662fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 663fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 6644342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 6659a844cf78f09953145200b4074d47589257a408cAravind Akella if (mWakeLockAcquired && !needsWakeLock) { 666b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella setWakeLockAcquiredLocked(false); 6679a844cf78f09953145200b4074d47589257a408cAravind Akella } 6688493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } while (!Thread::exitPending()); 669fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 6703c20fbed7f3a916ced10f2ed5a272271b7d81edeSteve Block ALOGW("Exiting SensorService::threadLoop => aborting..."); 6711a62301fc58cd2af18239b0415813461bf5fc41bMathias Agopian abort(); 672fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return false; 673fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 674fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 67556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellasp<Looper> SensorService::getLooper() const { 67656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella return mLooper; 67756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella} 67856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 679b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::resetAllWakeLockRefCounts() { 680b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella SortedVector< sp<SensorEventConnection> > activeConnections; 681b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella populateActiveConnections(&activeConnections); 682b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella { 683b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella Mutex::Autolock _l(mLock); 684b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella for (size_t i=0 ; i < activeConnections.size(); ++i) { 685b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (activeConnections[i] != 0) { 686b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella activeConnections[i]->resetWakeLockRefCount(); 687b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 688b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 689b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella setWakeLockAcquiredLocked(false); 690b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 691b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella} 692b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella 693b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::setWakeLockAcquiredLocked(bool acquire) { 694b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (acquire) { 695b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (!mWakeLockAcquired) { 696b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME); 697b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mWakeLockAcquired = true; 698b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 699b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mLooper->wake(); 700b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } else { 701b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (mWakeLockAcquired) { 702b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella release_wake_lock(WAKE_LOCK_NAME); 703b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mWakeLockAcquired = false; 704b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 705b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 706b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella} 707b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella 708b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellabool SensorService::isWakeLockAcquired() { 709b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella Mutex::Autolock _l(mLock); 710b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella return mWakeLockAcquired; 711b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella} 712b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella 71356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellabool SensorService::SensorEventAckReceiver::threadLoop() { 71456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella ALOGD("new thread SensorEventAckReceiver"); 715b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella sp<Looper> looper = mService->getLooper(); 71656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella do { 717b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella bool wakeLockAcquired = mService->isWakeLockAcquired(); 718b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella int timeout = -1; 719b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (wakeLockAcquired) timeout = 5000; 720b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella int ret = looper->pollOnce(timeout); 721b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (ret == ALOOPER_POLL_TIMEOUT) { 722b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mService->resetAllWakeLockRefCounts(); 723b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 72456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } while(!Thread::exitPending()); 72556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella return false; 72656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella} 72756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 7289a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::recordLastValueLocked( 7294b84704b97300eff3ebfab85652e64d54149d205Aravind Akella const sensors_event_t* buffer, size_t count) { 7304b84704b97300eff3ebfab85652e64d54149d205Aravind Akella for (size_t i = 0; i < count; i++) { 7312576cb63b3fe1592f54816625036566b9eb0793aPeng Xu if (buffer[i].type == SENSOR_TYPE_META_DATA || 7322576cb63b3fe1592f54816625036566b9eb0793aPeng Xu buffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META || 7336a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO) { 7342576cb63b3fe1592f54816625036566b9eb0793aPeng Xu continue; 7352576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 7362576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 7376a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu auto logger = mRecentEvent.find(buffer[i].sensor); 7386a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu if (logger != mRecentEvent.end()) { 7396a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu logger->second->addEvent(buffer[i]); 74094e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian } 74194e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian } 74294e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian} 74394e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian 74447e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xuvoid SensorService::sortEventBuffer(sensors_event_t* buffer, size_t count) { 745f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian struct compar { 746f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian static int cmp(void const* lhs, void const* rhs) { 747f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sensors_event_t const* l = static_cast<sensors_event_t const*>(lhs); 748f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sensors_event_t const* r = static_cast<sensors_event_t const*>(rhs); 749a5c106a4f0afcf061728a1cb7c8c3b908728575dMathias Agopian return l->timestamp - r->timestamp; 750f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 751f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian }; 752f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian qsort(buffer, count, sizeof(sensors_event_t), compar::cmp); 753f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian} 754f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 7555d2707214dfb97bd8dfcc6620be36841d3c82420Mathias AgopianString8 SensorService::getSensorName(int handle) const { 7560cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return mSensors.getName(handle); 7575d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian} 7585d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian 759b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akellabool SensorService::isVirtualSensor(int handle) const { 760755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 761755c451c7861a029e26e5f16e319b629169e656dPeng Xu return sensor != nullptr && sensor->isVirtual(); 762b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella} 763b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella 7649a844cf78f09953145200b4074d47589257a408cAravind Akellabool SensorService::isWakeUpSensorEvent(const sensors_event_t& event) const { 7657869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan int handle = event.sensor; 7667869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan if (event.type == SENSOR_TYPE_META_DATA) { 7677869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan handle = event.meta_data.sensor; 7687869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan } 769755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 770755c451c7861a029e26e5f16e319b629169e656dPeng Xu return sensor != nullptr && sensor->getSensor().isWakeUpSensor(); 7719a844cf78f09953145200b4074d47589257a408cAravind Akella} 7729a844cf78f09953145200b4074d47589257a408cAravind Akella 77353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiserint32_t SensorService::getIdFromUuid(const Sensor::uuid_t &uuid) const { 77453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if ((uuid.i64[0] == 0) && (uuid.i64[1] == 0)) { 77553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // UUID is not supported for this device. 77653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return 0; 77753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 77853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if ((uuid.i64[0] == INT64_C(~0)) && (uuid.i64[1] == INT64_C(~0))) { 77953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // This sensor can be uniquely identified in the system by 78053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // the combination of its type and name. 78153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return -1; 78253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 78353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 78453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // We have a dynamic sensor. 78553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 78653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (!sHmacGlobalKeyIsValid) { 78753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Rather than risk exposing UUIDs, we cripple dynamic sensors. 78853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser ALOGW("HMAC key failure; dynamic sensor getId() will be wrong."); 78953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return 0; 79053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 79153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 79253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // We want each app author/publisher to get a different ID, so that the 79353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // same dynamic sensor cannot be tracked across apps by multiple 79453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // authors/publishers. So we use both our UUID and our User ID. 79553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Note potential confusion: 79653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // UUID => Universally Unique Identifier. 79753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // UID => User Identifier. 79853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // We refrain from using "uid" except as needed by API to try to 79953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // keep this distinction clear. 80053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 80153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser auto appUserId = IPCThreadState::self()->getCallingUid(); 80253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser uint8_t uuidAndApp[sizeof(uuid) + sizeof(appUserId)]; 80353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser memcpy(uuidAndApp, &uuid, sizeof(uuid)); 80453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser memcpy(uuidAndApp + sizeof(uuid), &appUserId, sizeof(appUserId)); 80553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 80653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Now we use our key on our UUID/app combo to get the hash. 80753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser uint8_t hash[EVP_MAX_MD_SIZE]; 80853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser unsigned int hashLen; 80953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (HMAC(EVP_sha256(), 81053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser sHmacGlobalKey, sizeof(sHmacGlobalKey), 81153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser uuidAndApp, sizeof(uuidAndApp), 81253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser hash, &hashLen) == nullptr) { 81353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Rather than risk exposing UUIDs, we cripple dynamic sensors. 81453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser ALOGW("HMAC failure; dynamic sensor getId() will be wrong."); 81553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return 0; 81653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 81753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 81853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser int32_t id = 0; 81953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (hashLen < sizeof(id)) { 82053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // We never expect this case, but out of paranoia, we handle it. 82153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Our 'id' length is already quite small, we don't want the 82253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // effective length of it to be even smaller. 82353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Rather than risk exposing UUIDs, we cripple dynamic sensors. 82453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser ALOGW("HMAC insufficient; dynamic sensor getId() will be wrong."); 82553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return 0; 82653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 82753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 82853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // This is almost certainly less than all of 'hash', but it's as secure 82953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // as we can be with our current 'id' length. 83053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser memcpy(&id, hash, sizeof(id)); 83153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 83253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Note at the beginning of the function that we return the values of 83353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // 0 and -1 to represent special cases. As a result, we can't return 83453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // those as dynamic sensor IDs. If we happened to hash to one of those 83553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // values, we change 'id' so we report as a dynamic sensor, and not as 83653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // one of those special cases. 83753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (id == -1) { 83853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser id = -2; 83953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } else if (id == 0) { 84053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser id = 1; 84153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 84253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return id; 84353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser} 84453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 84553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiservoid SensorService::makeUuidsIntoIdsForSensorList(Vector<Sensor> &sensorList) const { 84653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser for (auto &sensor : sensorList) { 84753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser int32_t id = getIdFromUuid(sensor.getUuid()); 84853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser sensor.setId(id); 84953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 85053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser} 85153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 85247e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng XuVector<Sensor> SensorService::getSensorList(const String16& opPackageName) { 85333264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian char value[PROPERTY_VALUE_MAX]; 85433264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian property_get("debug.sensors", value, "0"); 855700180487ffec09d9df1657b018a7caadac24b75Aravind Akella const Vector<Sensor>& initialSensorList = (atoi(value)) ? 8560cc8f809924706c7d683da30605f432635dd5bb6Peng Xu mSensors.getUserDebugSensors() : mSensors.getUserSensors(); 857700180487ffec09d9df1657b018a7caadac24b75Aravind Akella Vector<Sensor> accessibleSensorList; 858700180487ffec09d9df1657b018a7caadac24b75Aravind Akella for (size_t i = 0; i < initialSensorList.size(); i++) { 859700180487ffec09d9df1657b018a7caadac24b75Aravind Akella Sensor sensor = initialSensorList[i]; 860b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (canAccessSensor(sensor, "getSensorList", opPackageName)) { 861700180487ffec09d9df1657b018a7caadac24b75Aravind Akella accessibleSensorList.add(sensor); 862700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } else { 863b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav ALOGI("Skipped sensor %s because it requires permission %s and app op %d", 8645f6199373dc1e07d2ee5edbae7ecfa08a065492eBernhard Rosenkränzer sensor.getName().string(), 865b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav sensor.getRequiredPermission().string(), 866b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav sensor.getRequiredAppOp()); 867700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } 86833264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian } 86953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser makeUuidsIntoIdsForSensorList(accessibleSensorList); 870700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return accessibleSensorList; 871fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 872fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 87347e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng XuVector<Sensor> SensorService::getDynamicSensorList(const String16& opPackageName) { 8742576cb63b3fe1592f54816625036566b9eb0793aPeng Xu Vector<Sensor> accessibleSensorList; 8750cc8f809924706c7d683da30605f432635dd5bb6Peng Xu mSensors.forEachSensor( 8760cc8f809924706c7d683da30605f432635dd5bb6Peng Xu [&opPackageName, &accessibleSensorList] (const Sensor& sensor) -> bool { 877755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (sensor.isDynamicSensor()) { 878755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (canAccessSensor(sensor, "getDynamicSensorList", opPackageName)) { 879755c451c7861a029e26e5f16e319b629169e656dPeng Xu accessibleSensorList.add(sensor); 880755c451c7861a029e26e5f16e319b629169e656dPeng Xu } else { 881755c451c7861a029e26e5f16e319b629169e656dPeng Xu ALOGI("Skipped sensor %s because it requires permission %s and app op %" PRId32, 882755c451c7861a029e26e5f16e319b629169e656dPeng Xu sensor.getName().string(), 883755c451c7861a029e26e5f16e319b629169e656dPeng Xu sensor.getRequiredPermission().string(), 884755c451c7861a029e26e5f16e319b629169e656dPeng Xu sensor.getRequiredAppOp()); 885755c451c7861a029e26e5f16e319b629169e656dPeng Xu } 8860cc8f809924706c7d683da30605f432635dd5bb6Peng Xu } 8870cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return true; 8880cc8f809924706c7d683da30605f432635dd5bb6Peng Xu }); 88953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser makeUuidsIntoIdsForSensorList(accessibleSensorList); 8902576cb63b3fe1592f54816625036566b9eb0793aPeng Xu return accessibleSensorList; 8912576cb63b3fe1592f54816625036566b9eb0793aPeng Xu} 8922576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 893a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellasp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName, 894b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav int requestedMode, const String16& opPackageName) { 895a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella // Only 2 modes supported for a SensorEventConnection ... NORMAL and DATA_INJECTION. 896a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella if (requestedMode != NORMAL && requestedMode != DATA_INJECTION) { 897a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella return NULL; 898a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella } 899a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella 900a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella Mutex::Autolock _l(mLock); 901841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella // To create a client in DATA_INJECTION mode to inject data, SensorService should already be 902841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella // operating in DI mode. 903841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (requestedMode == DATA_INJECTION) { 904841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (mCurrentOperatingMode != DATA_INJECTION) return NULL; 905841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (!isWhiteListedPackage(packageName)) return NULL; 906841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } 907841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella 9085307d17fe33fc26eeeacd6339a9fbfe96cf56873Mathias Agopian uid_t uid = IPCThreadState::self()->getCallingUid(); 909a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella sp<SensorEventConnection> result(new SensorEventConnection(this, uid, packageName, 910b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav requestedMode == DATA_INJECTION, opPackageName)); 911a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella if (requestedMode == DATA_INJECTION) { 912a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella if (mActiveConnections.indexOf(result) < 0) { 913a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella mActiveConnections.add(result); 914a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella } 915a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella // Add the associated file descriptor to the Looper for polling whenever there is data to 916a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella // be injected. 917a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella result->updateLooperRegistration(mLooper); 918a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella } 919fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return result; 920fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 921fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 922841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akellaint SensorService::isDataInjectionEnabled() { 923a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella Mutex::Autolock _l(mLock); 924841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella return (mCurrentOperatingMode == DATA_INJECTION); 925a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella} 926a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella 927a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatus_t SensorService::resetToNormalMode() { 928a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella Mutex::Autolock _l(mLock); 929a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella return resetToNormalModeLocked(); 930a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella} 931a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella 932a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatus_t SensorService::resetToNormalModeLocked() { 933a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella SensorDevice& dev(SensorDevice::getInstance()); 934a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella status_t err = dev.setMode(NORMAL); 935bfac17eed90d410de51413ef2484f79fb0e241e2Aniroop Mathur if (err == NO_ERROR) { 936bfac17eed90d410de51413ef2484f79fb0e241e2Aniroop Mathur mCurrentOperatingMode = NORMAL; 937bfac17eed90d410de51413ef2484f79fb0e241e2Aniroop Mathur dev.enableAllSensors(); 938bfac17eed90d410de51413ef2484f79fb0e241e2Aniroop Mathur } 939a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella return err; 940a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella} 941a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella 94247e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xuvoid SensorService::cleanupConnection(SensorEventConnection* c) { 943fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian Mutex::Autolock _l(mLock); 944db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian const wp<SensorEventConnection> connection(c); 9457c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian size_t size = mActiveSensors.size(); 946db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn ALOGD_IF(DEBUG_CONNECTIONS, "%zu active sensors", size); 9477c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian for (size_t i=0 ; i<size ; ) { 948db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian int handle = mActiveSensors.keyAt(i); 949db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian if (c->hasSensor(handle)) { 950db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn ALOGD_IF(DEBUG_CONNECTIONS, "%zu: disabling handle=0x%08x", i, handle); 951755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 952755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (sensor != nullptr) { 953db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian sensor->activate(c, false); 954755c451c7861a029e26e5f16e319b629169e656dPeng Xu } else { 955755c451c7861a029e26e5f16e319b629169e656dPeng Xu ALOGE("sensor interface of handle=0x%08x is null!", handle); 956f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 9578a96955c8e14db40b16164236830fc9506a00872Aravind Akella c->removeSensor(handle); 958db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian } 959db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian SensorRecord* rec = mActiveSensors.valueAt(i); 960db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn ALOGE_IF(!rec, "mActiveSensors[%zu] is null (handle=0x%08x)!", i, handle); 961a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block ALOGD_IF(DEBUG_CONNECTIONS, 962db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn "removing connection %p for sensor[%zu].handle=0x%08x", 963a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian c, i, handle); 964a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian 965db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian if (rec && rec->removeConnection(connection)) { 966a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block ALOGD_IF(DEBUG_CONNECTIONS, "... and it was the last connection"); 9677c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian mActiveSensors.removeItemsAt(i, 1); 968755c451c7861a029e26e5f16e319b629169e656dPeng Xu mActiveVirtualSensors.erase(handle); 9697c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian delete rec; 9707c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian size--; 9717c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian } else { 9727c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian i++; 973fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 974fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 9758a96955c8e14db40b16164236830fc9506a00872Aravind Akella c->updateLooperRegistration(mLooper); 9767c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian mActiveConnections.remove(connection); 977787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian BatteryService::cleanup(c->getUid()); 9789a844cf78f09953145200b4074d47589257a408cAravind Akella if (c->needsWakeLock()) { 9799a844cf78f09953145200b4074d47589257a408cAravind Akella checkWakeLockStateLocked(); 9809a844cf78f09953145200b4074d47589257a408cAravind Akella } 981fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 982fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 983755c451c7861a029e26e5f16e319b629169e656dPeng Xusp<SensorInterface> SensorService::getSensorInterfaceFromHandle(int handle) const { 9840cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return mSensors.getInterface(handle); 98547e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu} 98647e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu 987700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 988fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::enable(const sp<SensorEventConnection>& connection, 989b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags, 99047e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu const String16& opPackageName) { 99150df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian if (mInitCheck != NO_ERROR) 99250df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian return mInitCheck; 99350df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian 994755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 995755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (sensor == nullptr || 996755c451c7861a029e26e5f16e319b629169e656dPeng Xu !canAccessSensor(sensor->getSensor(), "Tried enabling", opPackageName)) { 997700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return BAD_VALUE; 998700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } 999700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 1000ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian Mutex::Autolock _l(mLock); 1001841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if ((mCurrentOperatingMode == RESTRICTED || mCurrentOperatingMode == DATA_INJECTION) 1002841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella && !isWhiteListedPackage(connection->getPackageName())) { 10034949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella return INVALID_OPERATION; 10044949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella } 10054949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella 10064342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh SensorRecord* rec = mActiveSensors.valueFor(handle); 10074342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (rec == 0) { 10084342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh rec = new SensorRecord(connection); 10094342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh mActiveSensors.add(handle, rec); 10104342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (sensor->isVirtual()) { 1011755c451c7861a029e26e5f16e319b629169e656dPeng Xu mActiveVirtualSensors.emplace(handle); 10123560fb24b668675627934356f210d84d19bf4e56Mathias Agopian } 10134342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } else { 10144342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (rec->addConnection(connection)) { 10159a844cf78f09953145200b4074d47589257a408cAravind Akella // this sensor is already activated, but we are adding a connection that uses it. 10169a844cf78f09953145200b4074d47589257a408cAravind Akella // Immediately send down the last known value of the requested sensor if it's not a 10174342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // "continuous" sensor. 10180e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ON_CHANGE) { 10199a844cf78f09953145200b4074d47589257a408cAravind Akella // NOTE: The wake_up flag of this event may get set to 10209a844cf78f09953145200b4074d47589257a408cAravind Akella // WAKE_UP_SENSOR_EVENT_NEEDS_ACK if this is a wake_up event. 10216a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 10226a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu auto logger = mRecentEvent.find(handle); 10236a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu if (logger != mRecentEvent.end()) { 1024444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella sensors_event_t event; 1025444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // It is unlikely that this buffer is empty as the sensor is already active. 1026444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // One possible corner case may be two applications activating an on-change 1027444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // sensor at the same time. 10286a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu if(logger->second->populateLastEvent(&event)) { 1029444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella event.sensor = handle; 1030444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (event.version == sizeof(sensors_event_t)) { 1031444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (isWakeUpSensorEvent(event) && !mWakeLockAcquired) { 1032444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella setWakeLockAcquiredLocked(true); 1033444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 1034444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella connection->sendEvents(&event, 1, NULL); 1035444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (!connection->needsWakeLock() && mWakeLockAcquired) { 1036444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella checkWakeLockStateLocked(); 1037444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 1038444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 10399a844cf78f09953145200b4074d47589257a408cAravind Akella } 1040f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 10417c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian } 1042fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 1043fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 10444342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 10454342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (connection->addSensor(handle)) { 10464342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh BatteryService::enableSensor(connection->getUid(), handle); 10474342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // the sensor was added (which means it wasn't already there) 10484342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // so, see if this connection becomes active 10494342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (mActiveConnections.indexOf(connection) < 0) { 10504342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh mActiveConnections.add(connection); 10514342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 10524342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } else { 10534342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh ALOGW("sensor %08x already enabled in connection %p (ignoring)", 10544342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh handle, connection.get()); 10554342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 10564342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 1057724d91d778e71c8186399f4955de14b54812b3edAravind Akella nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs(); 1058724d91d778e71c8186399f4955de14b54812b3edAravind Akella if (samplingPeriodNs < minDelayNs) { 1059724d91d778e71c8186399f4955de14b54812b3edAravind Akella samplingPeriodNs = minDelayNs; 1060724d91d778e71c8186399f4955de14b54812b3edAravind Akella } 1061724d91d778e71c8186399f4955de14b54812b3edAravind Akella 10626c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d" 10636c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella "rate=%" PRId64 " timeout== %" PRId64"", 1064724d91d778e71c8186399f4955de14b54812b3edAravind Akella handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs); 1065724d91d778e71c8186399f4955de14b54812b3edAravind Akella 10664949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella status_t err = sensor->batch(connection.get(), handle, 0, samplingPeriodNs, 1067724d91d778e71c8186399f4955de14b54812b3edAravind Akella maxBatchReportLatencyNs); 10686c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 106920483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // Call flush() before calling activate() on the sensor. Wait for a first 107020483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // flush complete event before sending events on this connection. Ignore 107120483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // one-shot sensors which don't support flush(). Ignore on-change sensors 107220483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // to maintain the on-change logic (any on-change events except the initial 107320483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // one should be trigger by a change in value). Also if this sensor isn't 107420483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // already active, don't call flush(). 107520483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu if (err == NO_ERROR && 10762576cb63b3fe1592f54816625036566b9eb0793aPeng Xu sensor->getSensor().getReportingMode() == AREPORTING_MODE_CONTINUOUS && 10775466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella rec->getNumConnections() > 1) { 10785466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella connection->setFirstFlushPending(handle, true); 10794c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella status_t err_flush = sensor->flush(connection.get(), handle); 10805466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // Flush may return error if the underlying h/w sensor uses an older HAL. 10816c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella if (err_flush == NO_ERROR) { 10826c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella rec->addPendingFlushConnection(connection.get()); 10835466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella } else { 10845466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella connection->setFirstFlushPending(handle, false); 10854c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 10864c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 1087724d91d778e71c8186399f4955de14b54812b3edAravind Akella 1088724d91d778e71c8186399f4955de14b54812b3edAravind Akella if (err == NO_ERROR) { 1089724d91d778e71c8186399f4955de14b54812b3edAravind Akella ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle); 1090724d91d778e71c8186399f4955de14b54812b3edAravind Akella err = sensor->activate(connection.get(), true); 1091724d91d778e71c8186399f4955de14b54812b3edAravind Akella } 1092724d91d778e71c8186399f4955de14b54812b3edAravind Akella 10938a96955c8e14db40b16164236830fc9506a00872Aravind Akella if (err == NO_ERROR) { 10948a96955c8e14db40b16164236830fc9506a00872Aravind Akella connection->updateLooperRegistration(mLooper); 109518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella SensorRegistrationInfo ®_info = 109618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex); 109718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mSensorHandle = handle; 109818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mSamplingRateUs = samplingPeriodNs/1000; 109918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mMaxReportLatencyUs = maxBatchReportLatencyNs/1000; 110018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mActivated = true; 110118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mPackageName = connection->getPackageName(); 110218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella time_t rawtime = time(NULL); 110318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella struct tm * timeinfo = localtime(&rawtime); 110418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mHour = timeinfo->tm_hour; 110518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mMin = timeinfo->tm_min; 110618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mSec = timeinfo->tm_sec; 110718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mNextSensorRegIndex = (mNextSensorRegIndex + 1) % SENSOR_REGISTRATIONS_BUF_SIZE; 110856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 110956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 11104342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (err != NO_ERROR) { 1111724d91d778e71c8186399f4955de14b54812b3edAravind Akella // batch/activate has failed, reset our state. 1112ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian cleanupWithoutDisableLocked(connection, handle); 11134342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 1114fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return err; 1115fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 1116fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 111747e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xustatus_t SensorService::disable(const sp<SensorEventConnection>& connection, int handle) { 111850df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian if (mInitCheck != NO_ERROR) 111950df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian return mInitCheck; 112050df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian 1121ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian Mutex::Autolock _l(mLock); 1122ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian status_t err = cleanupWithoutDisableLocked(connection, handle); 11234342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (err == NO_ERROR) { 1124755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 1125755c451c7861a029e26e5f16e319b629169e656dPeng Xu err = sensor != nullptr ? sensor->activate(connection.get(), false) : status_t(BAD_VALUE); 112618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella 112718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } 112818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella if (err == NO_ERROR) { 112918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella SensorRegistrationInfo ®_info = 113018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex); 113118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mActivated = false; 113218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mPackageName= connection->getPackageName(); 113318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mSensorHandle = handle; 113418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella time_t rawtime = time(NULL); 113518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella struct tm * timeinfo = localtime(&rawtime); 113618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mHour = timeinfo->tm_hour; 113718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mMin = timeinfo->tm_min; 113818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mSec = timeinfo->tm_sec; 113918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mNextSensorRegIndex = (mNextSensorRegIndex + 1) % SENSOR_REGISTRATIONS_BUF_SIZE; 11404342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 11414342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh return err; 11424342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh} 11434342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 1144ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisable( 1145ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian const sp<SensorEventConnection>& connection, int handle) { 1146fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian Mutex::Autolock _l(mLock); 1147ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian return cleanupWithoutDisableLocked(connection, handle); 1148ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian} 1149ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian 1150ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisableLocked( 1151ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian const sp<SensorEventConnection>& connection, int handle) { 1152fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian SensorRecord* rec = mActiveSensors.valueFor(handle); 1153fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian if (rec) { 1154fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian // see if this connection becomes inactive 1155787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian if (connection->removeSensor(handle)) { 1156787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian BatteryService::disableSensor(connection->getUid(), handle); 1157787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian } 1158fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian if (connection->hasAnySensor() == false) { 11598a96955c8e14db40b16164236830fc9506a00872Aravind Akella connection->updateLooperRegistration(mLooper); 1160fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian mActiveConnections.remove(connection); 1161fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 1162fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian // see if this sensor becomes inactive 1163fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian if (rec->removeConnection(connection)) { 1164fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian mActiveSensors.removeItem(handle); 1165755c451c7861a029e26e5f16e319b629169e656dPeng Xu mActiveVirtualSensors.erase(handle); 1166fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian delete rec; 1167fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 11684342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh return NO_ERROR; 11697c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian } 11704342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh return BAD_VALUE; 1171fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 1172fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 11737c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianstatus_t SensorService::setEventRate(const sp<SensorEventConnection>& connection, 117447e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu int handle, nsecs_t ns, const String16& opPackageName) { 117550df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian if (mInitCheck != NO_ERROR) 117650df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian return mInitCheck; 117750df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian 1178755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 1179755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (sensor == nullptr || 1180755c451c7861a029e26e5f16e319b629169e656dPeng Xu !canAccessSensor(sensor->getSensor(), "Tried configuring", opPackageName)) { 1181700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return BAD_VALUE; 1182700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } 1183700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 11841cd700015318727d6d42236ab6274f1949fb08baMathias Agopian if (ns < 0) 11851cd700015318727d6d42236ab6274f1949fb08baMathias Agopian return BAD_VALUE; 11861cd700015318727d6d42236ab6274f1949fb08baMathias Agopian 118762569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs(); 118862569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian if (ns < minDelayNs) { 118962569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian ns = minDelayNs; 1190ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian } 1191ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian 1192f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian return sensor->setDelay(connection.get(), handle, ns); 1193fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 1194fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 1195b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslavstatus_t SensorService::flushSensor(const sp<SensorEventConnection>& connection, 1196b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav const String16& opPackageName) { 1197700180487ffec09d9df1657b018a7caadac24b75Aravind Akella if (mInitCheck != NO_ERROR) return mInitCheck; 11989e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella SensorDevice& dev(SensorDevice::getInstance()); 11999e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella const int halVersion = dev.getHalDeviceVersion(); 12009e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella status_t err(NO_ERROR); 12019e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella Mutex::Autolock _l(mLock); 12029e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // Loop through all sensors for this connection and call flush on each of them. 12039e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella for (size_t i = 0; i < connection->mSensorInfo.size(); ++i) { 12049e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella const int handle = connection->mSensorInfo.keyAt(i); 1205755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 1206755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (sensor == nullptr) { 1207755c451c7861a029e26e5f16e319b629169e656dPeng Xu continue; 1208755c451c7861a029e26e5f16e319b629169e656dPeng Xu } 12099e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) { 12109e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella ALOGE("flush called on a one-shot sensor"); 12119e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella err = INVALID_OPERATION; 12129e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella continue; 12139e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } 12148493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (halVersion <= SENSORS_DEVICE_API_VERSION_1_0 || isVirtualSensor(handle)) { 12159e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // For older devices just increment pending flush count which will send a trivial 12169e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // flush complete event. 12178a96955c8e14db40b16164236830fc9506a00872Aravind Akella connection->incrementPendingFlushCount(handle); 12189e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } else { 1219b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (!canAccessSensor(sensor->getSensor(), "Tried flushing", opPackageName)) { 1220b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav err = INVALID_OPERATION; 1221b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav continue; 1222b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav } 12239e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella status_t err_flush = sensor->flush(connection.get(), handle); 12249e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella if (err_flush == NO_ERROR) { 12259e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella SensorRecord* rec = mActiveSensors.valueFor(handle); 12269e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella if (rec != NULL) rec->addPendingFlushConnection(connection); 12279e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } 12289e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella err = (err_flush != NO_ERROR) ? err_flush : err; 12299e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } 12306c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } 12319e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella return err; 1232700180487ffec09d9df1657b018a7caadac24b75Aravind Akella} 1233700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 1234b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslavbool SensorService::canAccessSensor(const Sensor& sensor, const char* operation, 1235b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav const String16& opPackageName) { 1236b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav const String8& requiredPermission = sensor.getRequiredPermission(); 1237700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 1238b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (requiredPermission.length() <= 0) { 1239700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return true; 1240b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav } 1241b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav 1242b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav bool hasPermission = false; 1243b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav 1244b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav // Runtime permissions can't use the cache as they may change. 1245b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (sensor.isRequiredPermissionRuntime()) { 1246b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav hasPermission = checkPermission(String16(requiredPermission), 1247b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav IPCThreadState::self()->getCallingPid(), IPCThreadState::self()->getCallingUid()); 1248700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } else { 1249b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav hasPermission = PermissionCache::checkCallingPermission(String16(requiredPermission)); 1250b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav } 1251b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav 1252b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (!hasPermission) { 1253b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav ALOGE("%s a sensor (%s) without holding its required permission: %s", 1254b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav operation, sensor.getName().string(), sensor.getRequiredPermission().string()); 1255700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return false; 1256700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } 1257b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav 1258b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav const int32_t opCode = sensor.getRequiredAppOp(); 1259b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (opCode >= 0) { 1260b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav AppOpsManager appOps; 1261b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (appOps.noteOp(opCode, IPCThreadState::self()->getCallingUid(), opPackageName) 1262b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav != AppOpsManager::MODE_ALLOWED) { 1263d4036b6b7f9609fe09efabdbfbb8c8f9428f76f7Andreas Gampe ALOGE("%s a sensor (%s) without enabled required app op: %d", 1264b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav operation, sensor.getName().string(), opCode); 1265b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav return false; 1266b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav } 1267b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav } 1268b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav 1269b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav return true; 1270700180487ffec09d9df1657b018a7caadac24b75Aravind Akella} 1271700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 12729a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockState() { 12739a844cf78f09953145200b4074d47589257a408cAravind Akella Mutex::Autolock _l(mLock); 12749a844cf78f09953145200b4074d47589257a408cAravind Akella checkWakeLockStateLocked(); 12759a844cf78f09953145200b4074d47589257a408cAravind Akella} 12769a844cf78f09953145200b4074d47589257a408cAravind Akella 12779a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockStateLocked() { 12789a844cf78f09953145200b4074d47589257a408cAravind Akella if (!mWakeLockAcquired) { 12799a844cf78f09953145200b4074d47589257a408cAravind Akella return; 12809a844cf78f09953145200b4074d47589257a408cAravind Akella } 12819a844cf78f09953145200b4074d47589257a408cAravind Akella bool releaseLock = true; 12829a844cf78f09953145200b4074d47589257a408cAravind Akella for (size_t i=0 ; i<mActiveConnections.size() ; i++) { 12839a844cf78f09953145200b4074d47589257a408cAravind Akella sp<SensorEventConnection> connection(mActiveConnections[i].promote()); 12849a844cf78f09953145200b4074d47589257a408cAravind Akella if (connection != 0) { 12859a844cf78f09953145200b4074d47589257a408cAravind Akella if (connection->needsWakeLock()) { 12869a844cf78f09953145200b4074d47589257a408cAravind Akella releaseLock = false; 12879a844cf78f09953145200b4074d47589257a408cAravind Akella break; 12889a844cf78f09953145200b4074d47589257a408cAravind Akella } 12899a844cf78f09953145200b4074d47589257a408cAravind Akella } 12909a844cf78f09953145200b4074d47589257a408cAravind Akella } 12919a844cf78f09953145200b4074d47589257a408cAravind Akella if (releaseLock) { 1292b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella setWakeLockAcquiredLocked(false); 1293b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 1294b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella} 1295b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella 1296b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::sendEventsFromCache(const sp<SensorEventConnection>& connection) { 1297b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella Mutex::Autolock _l(mLock); 1298b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella connection->writeToSocketFromCache(); 1299b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (connection->needsWakeLock()) { 1300b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella setWakeLockAcquiredLocked(true); 1301b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 1302b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella} 1303b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella 1304b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::populateActiveConnections( 1305b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella SortedVector< sp<SensorEventConnection> >* activeConnections) { 1306b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella Mutex::Autolock _l(mLock); 1307b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella for (size_t i=0 ; i < mActiveConnections.size(); ++i) { 1308b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella sp<SensorEventConnection> connection(mActiveConnections[i].promote()); 1309b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (connection != 0) { 1310b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella activeConnections->add(connection); 1311b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 13129a844cf78f09953145200b4074d47589257a408cAravind Akella } 13139a844cf78f09953145200b4074d47589257a408cAravind Akella} 13146c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 13154949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akellabool SensorService::isWhiteListedPackage(const String8& packageName) { 1316841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella return (packageName.contains(mWhiteListedPackage.string())); 13174949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella} 13184949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella 1319fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}; // namespace android 1320fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 1321