SensorService.cpp revision 2c588c536090ea3e7e80db0e5031935b6026814c
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> 5098d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu#include <sched.h> 51eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <stdint.h> 52eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <sys/socket.h> 5353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <sys/stat.h> 5453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <sys/types.h> 5553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <unistd.h> 56fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 57fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopiannamespace android { 58fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// --------------------------------------------------------------------------- 59fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 603301542828febc768e1df42892cfac4992c35474Mathias Agopian/* 613301542828febc768e1df42892cfac4992c35474Mathias Agopian * Notes: 623301542828febc768e1df42892cfac4992c35474Mathias Agopian * 633301542828febc768e1df42892cfac4992c35474Mathias Agopian * - what about a gyro-corrected magnetic-field sensor? 643301542828febc768e1df42892cfac4992c35474Mathias Agopian * - run mag sensor from time to time to force calibration 653301542828febc768e1df42892cfac4992c35474Mathias Agopian * - gravity sensor length is wrong (=> drift in linear-acc sensor) 663301542828febc768e1df42892cfac4992c35474Mathias Agopian * 673301542828febc768e1df42892cfac4992c35474Mathias Agopian */ 683301542828febc768e1df42892cfac4992c35474Mathias Agopian 698ef3c89eb2030395f8a342bd16dbb344957ab275Aravind Akellaconst char* SensorService::WAKE_LOCK_NAME = "SensorService_wakelock"; 7053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiseruint8_t SensorService::sHmacGlobalKey[128] = {}; 7153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiserbool SensorService::sHmacGlobalKeyIsValid = false; 7253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 7353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#define SENSOR_SERVICE_DIR "/data/system/sensor_service" 7453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#define SENSOR_SERVICE_HMAC_KEY_FILE SENSOR_SERVICE_DIR "/hmac_key" 7598d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu#define SENSOR_SERVICE_SCHED_FIFO_PRIORITY 10 7653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 77a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella// Permissions. 78a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatic const String16 sDump("android.permission.DUMP"); 794342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 80fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorService() 818a96955c8e14db40b16164236830fc9506a00872Aravind Akella : mInitCheck(NO_INIT), mSocketBufferSize(SOCKET_BUFFER_SIZE_NON_BATCHED), 8247e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu mWakeLockAcquired(false) { 83fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 84fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 8553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiserbool SensorService::initializeHmacKey() { 8653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser int fd = open(SENSOR_SERVICE_HMAC_KEY_FILE, O_RDONLY|O_CLOEXEC); 8753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (fd != -1) { 8853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser int result = read(fd, sHmacGlobalKey, sizeof(sHmacGlobalKey)); 8953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser close(fd); 9053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (result == sizeof(sHmacGlobalKey)) { 9153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return true; 9253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 9353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser ALOGW("Unable to read HMAC key; generating new one."); 9453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 9553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 9653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (RAND_bytes(sHmacGlobalKey, sizeof(sHmacGlobalKey)) == -1) { 9753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser ALOGW("Can't generate HMAC key; dynamic sensor getId() will be wrong."); 9853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return false; 9953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 10053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 10153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // We need to make sure this is only readable to us. 10253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser bool wroteKey = false; 10353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser mkdir(SENSOR_SERVICE_DIR, S_IRWXU); 10453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser fd = open(SENSOR_SERVICE_HMAC_KEY_FILE, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, 10553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser S_IRUSR|S_IWUSR); 10653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (fd != -1) { 10753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser int result = write(fd, sHmacGlobalKey, sizeof(sHmacGlobalKey)); 10853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser close(fd); 10953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser wroteKey = (result == sizeof(sHmacGlobalKey)); 11053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 11153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (wroteKey) { 11253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser ALOGI("Generated new HMAC key."); 11353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } else { 11453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser ALOGW("Unable to write HMAC key; dynamic sensor getId() will change " 11553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser "after reboot."); 11653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 11753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Even if we failed to write the key we return true, because we did 11853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // initialize the HMAC key. 11953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return true; 12053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser} 12153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 12298d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu// Set main thread to SCHED_FIFO to lower sensor event latency when system is under load 12398d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xuvoid SensorService::enableSchedFifoMode() { 12498d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu struct sched_param param = {0}; 12598d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu param.sched_priority = SENSOR_SERVICE_SCHED_FIFO_PRIORITY; 12698d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu if (sched_setscheduler(getTid(), SCHED_FIFO | SCHED_RESET_ON_FORK, ¶m) != 0) { 12798d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu ALOGE("Couldn't set SCHED_FIFO for SensorService thread"); 12898d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu } 12998d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu} 13098d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu 13147e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xuvoid SensorService::onFirstRef() { 132a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block ALOGD("nuSensorService starting..."); 133f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian SensorDevice& dev(SensorDevice::getInstance()); 134fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 13553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser sHmacGlobalKeyIsValid = initializeHmacKey(); 13653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 137f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian if (dev.initCheck() == NO_ERROR) { 138f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sensor_t const* list; 1397b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian ssize_t count = dev.getSensorList(&list); 1407b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian if (count > 0) { 1417b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian ssize_t orientationIndex = -1; 142f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella bool hasGyro = false, hasAccel = false, hasMag = false; 1437b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian uint32_t virtualSensorsNeeds = 1447b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian (1<<SENSOR_TYPE_GRAVITY) | 1457b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian (1<<SENSOR_TYPE_LINEAR_ACCELERATION) | 146f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu (1<<SENSOR_TYPE_ROTATION_VECTOR) | 147f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR) | 148f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR); 1497b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian 1507b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian for (ssize_t i=0 ; i<count ; i++) { 151f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu bool useThisSensor=true; 152f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu 1537b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian switch (list[i].type) { 154f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella case SENSOR_TYPE_ACCELEROMETER: 155f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella hasAccel = true; 156f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella break; 157f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella case SENSOR_TYPE_MAGNETIC_FIELD: 158f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella hasMag = true; 159f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella break; 1607b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian case SENSOR_TYPE_ORIENTATION: 1617b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian orientationIndex = i; 1627b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian break; 1637b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian case SENSOR_TYPE_GYROSCOPE: 1640319306670b0344da99efa606b6f172dde575a39Mathias Agopian case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED: 1657b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian hasGyro = true; 1667b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian break; 1677b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian case SENSOR_TYPE_GRAVITY: 1687b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian case SENSOR_TYPE_LINEAR_ACCELERATION: 1697b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian case SENSOR_TYPE_ROTATION_VECTOR: 170f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR: 171f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu case SENSOR_TYPE_GAME_ROTATION_VECTOR: 172f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu if (IGNORE_HARDWARE_FUSION) { 173f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu useThisSensor = false; 174f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu } else { 175f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu virtualSensorsNeeds &= ~(1<<list[i].type); 176f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu } 1777b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian break; 1787b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian } 179f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu if (useThisSensor) { 180f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu registerSensor( new HardwareSensor(list[i]) ); 181f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu } 18250df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian } 183fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 1847b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian // it's safe to instantiate the SensorFusion object here 1857b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian // (it wants to be instantiated after h/w sensors have been 1867b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian // registered) 187d4036b6b7f9609fe09efabdbfbb8c8f9428f76f7Andreas Gampe SensorFusion::getInstance(); 1887b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian 189f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella if (hasGyro && hasAccel && hasMag) { 1900319306670b0344da99efa606b6f172dde575a39Mathias Agopian // Add Android virtual sensors if they're not already 1910319306670b0344da99efa606b6f172dde575a39Mathias Agopian // available in the HAL 1920cc8f809924706c7d683da30605f432635dd5bb6Peng Xu bool needRotationVector = 1930cc8f809924706c7d683da30605f432635dd5bb6Peng Xu (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) != 0; 1947b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian 1950cc8f809924706c7d683da30605f432635dd5bb6Peng Xu registerSensor(new RotationVectorSensor(), !needRotationVector, true); 1960cc8f809924706c7d683da30605f432635dd5bb6Peng Xu registerSensor(new OrientationSensor(), !needRotationVector, true); 197f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 1980cc8f809924706c7d683da30605f432635dd5bb6Peng Xu bool needLinearAcceleration = 1990cc8f809924706c7d683da30605f432635dd5bb6Peng Xu (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) != 0; 2000319306670b0344da99efa606b6f172dde575a39Mathias Agopian 2010cc8f809924706c7d683da30605f432635dd5bb6Peng Xu registerSensor(new LinearAccelerationSensor(list, count), 2020cc8f809924706c7d683da30605f432635dd5bb6Peng Xu !needLinearAcceleration, true); 203f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu 2040cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // virtual debugging sensors are not for user 205755c451c7861a029e26e5f16e319b629169e656dPeng Xu registerSensor( new CorrectedGyroSensor(list, count), true, true); 206755c451c7861a029e26e5f16e319b629169e656dPeng Xu registerSensor( new GyroDriftSensor(), true, true); 207010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian } 208010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian 209f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu if (hasAccel && hasGyro) { 2100cc8f809924706c7d683da30605f432635dd5bb6Peng Xu bool needGravitySensor = (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) != 0; 2110cc8f809924706c7d683da30605f432635dd5bb6Peng Xu registerSensor(new GravitySensor(list, count), !needGravitySensor, true); 212f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu 2130cc8f809924706c7d683da30605f432635dd5bb6Peng Xu bool needGameRotationVector = 2140cc8f809924706c7d683da30605f432635dd5bb6Peng Xu (virtualSensorsNeeds & (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR)) != 0; 2150cc8f809924706c7d683da30605f432635dd5bb6Peng Xu registerSensor(new GameRotationVectorSensor(), !needGameRotationVector, true); 216f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu } 217f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu 218f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu if (hasAccel && hasMag) { 2190cc8f809924706c7d683da30605f432635dd5bb6Peng Xu bool needGeoMagRotationVector = 2200cc8f809924706c7d683da30605f432635dd5bb6Peng Xu (virtualSensorsNeeds & (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR)) != 0; 2210cc8f809924706c7d683da30605f432635dd5bb6Peng Xu registerSensor(new GeoMagRotationVectorSensor(), !needGeoMagRotationVector, true); 222f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu } 223f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu 2245466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // Check if the device really supports batching by looking at the FIFO event 2255466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // counts for each sensor. 2265466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella bool batchingSupported = false; 2270cc8f809924706c7d683da30605f432635dd5bb6Peng Xu mSensors.forEachSensor( 2280cc8f809924706c7d683da30605f432635dd5bb6Peng Xu [&batchingSupported] (const Sensor& s) -> bool { 2290cc8f809924706c7d683da30605f432635dd5bb6Peng Xu if (s.getFifoMaxEventCount() > 0) { 2300cc8f809924706c7d683da30605f432635dd5bb6Peng Xu batchingSupported = true; 2310cc8f809924706c7d683da30605f432635dd5bb6Peng Xu } 2320cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return !batchingSupported; 2330cc8f809924706c7d683da30605f432635dd5bb6Peng Xu }); 2345466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella 2355466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella if (batchingSupported) { 2365466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // Increase socket buffer size to a max of 100 KB for batching capabilities. 2375466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella mSocketBufferSize = MAX_SOCKET_BUFFER_SIZE_BATCHED; 2385466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella } else { 2395466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella mSocketBufferSize = SOCKET_BUFFER_SIZE_NON_BATCHED; 2405466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella } 2415466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella 2425466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // Compare the socketBufferSize value against the system limits and limit 2435466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // it to maxSystemSocketBufferSize if necessary. 2444c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella FILE *fp = fopen("/proc/sys/net/core/wmem_max", "r"); 2454c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella char line[128]; 2464c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella if (fp != NULL && fgets(line, sizeof(line), fp) != NULL) { 2474c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella line[sizeof(line) - 1] = '\0'; 2485466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella size_t maxSystemSocketBufferSize; 2495466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella sscanf(line, "%zu", &maxSystemSocketBufferSize); 2505466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella if (mSocketBufferSize > maxSystemSocketBufferSize) { 2515466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella mSocketBufferSize = maxSystemSocketBufferSize; 2524c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 2534c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 2544c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella if (fp) { 2554c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella fclose(fp); 2564c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 2574c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella 2589a844cf78f09953145200b4074d47589257a408cAravind Akella mWakeLockAcquired = false; 25956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella mLooper = new Looper(false); 2608493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT; 2618493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mSensorEventBuffer = new sensors_event_t[minBufferSize]; 2628493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mSensorEventScratch = new sensors_event_t[minBufferSize]; 263eb05947ae2c4ac3a80712fed9382d82cb9aedad5Peng Xu mMapFlushEventsToConnections = new wp<const SensorEventConnection> [minBufferSize]; 264a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella mCurrentOperatingMode = NORMAL; 2657830ef3dd0ff3749d974c2dd85a8fa59dc47aecaAravind Akella 26618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mNextSensorRegIndex = 0; 26718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella for (int i = 0; i < SENSOR_REGISTRATIONS_BUF_SIZE; ++i) { 26818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mLastNSensorRegistrations.push(); 26918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } 27018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella 27118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mInitCheck = NO_ERROR; 272b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mAckReceiver = new SensorEventAckReceiver(this); 273b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY); 2747830ef3dd0ff3749d974c2dd85a8fa59dc47aecaAravind Akella run("SensorService", PRIORITY_URGENT_DISPLAY); 27598d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu 27698d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu // priority can only be changed after run 27798d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu enableSchedFifoMode(); 2787b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian } 279fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 280fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 281fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 2820cc8f809924706c7d683da30605f432635dd5bb6Peng Xuconst Sensor& SensorService::registerSensor(SensorInterface* s, bool isDebug, bool isVirtual) { 2830cc8f809924706c7d683da30605f432635dd5bb6Peng Xu int handle = s->getSensor().getHandle(); 2846a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu int type = s->getSensor().getType(); 2850cc8f809924706c7d683da30605f432635dd5bb6Peng Xu if (mSensors.add(handle, s, isDebug, isVirtual)){ 2866a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mRecentEvent.emplace(handle, new RecentEventLogger(type)); 2870cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return s->getSensor(); 2880cc8f809924706c7d683da30605f432635dd5bb6Peng Xu } else { 2890cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return mSensors.getNonSensor(); 2900cc8f809924706c7d683da30605f432635dd5bb6Peng Xu } 291f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian} 292f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 2936a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xuconst Sensor& SensorService::registerDynamicSensorLocked(SensorInterface* s, bool isDebug) { 2940cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return registerSensor(s, isDebug); 2952576cb63b3fe1592f54816625036566b9eb0793aPeng Xu} 2962576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 2976a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xubool SensorService::unregisterDynamicSensorLocked(int handle) { 2980cc8f809924706c7d683da30605f432635dd5bb6Peng Xu bool ret = mSensors.remove(handle); 2996a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 3006a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu const auto i = mRecentEvent.find(handle); 3016a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu if (i != mRecentEvent.end()) { 3026a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu delete i->second; 3036a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mRecentEvent.erase(i); 3042576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 3050cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return ret; 306f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian} 307f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 3080cc8f809924706c7d683da30605f432635dd5bb6Peng Xuconst Sensor& SensorService::registerVirtualSensor(SensorInterface* s, bool isDebug) { 3090cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return registerSensor(s, isDebug, true); 31047e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu} 31147e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu 31247e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng XuSensorService::~SensorService() { 3136a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu for (auto && entry : mRecentEvent) { 3146a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu delete entry.second; 3156a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu } 316fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 317fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 31847e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xustatus_t SensorService::dump(int fd, const Vector<String16>& args) { 319fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian String8 result; 3201cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian if (!PermissionCache::checkCallingPermission(sDump)) { 321eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu result.appendFormat("Permission Denial: can't dump SensorService from pid=%d, uid=%d\n", 322fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian IPCThreadState::self()->getCallingPid(), 323fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian IPCThreadState::self()->getCallingUid()); 324444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } else { 325fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu bool privileged = IPCThreadState::self()->getCallingUid() == 0; 326841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (args.size() > 2) { 3274949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella return INVALID_OPERATION; 3284949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella } 3294949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella Mutex::Autolock _l(mLock); 3304949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella SensorDevice& dev(SensorDevice::getInstance()); 331841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (args.size() == 2 && args[0] == String16("restrict")) { 332444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // If already in restricted mode. Ignore. 333444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (mCurrentOperatingMode == RESTRICTED) { 334444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella return status_t(NO_ERROR); 335444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 336444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // If in any mode other than normal, ignore. 337444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (mCurrentOperatingMode != NORMAL) { 338444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella return INVALID_OPERATION; 339444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 340a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella mCurrentOperatingMode = RESTRICTED; 3414949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella dev.disableAllSensors(); 3424949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella // Clear all pending flush connections for all active sensors. If one of the active 3434949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella // connections has called flush() and the underlying sensor has been disabled before a 3444949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella // flush complete event is returned, we need to remove the connection from this queue. 3454949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella for (size_t i=0 ; i< mActiveSensors.size(); ++i) { 3464949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella mActiveSensors.valueAt(i)->clearAllPendingFlushConnections(); 3474949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella } 348841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella mWhiteListedPackage.setTo(String8(args[1])); 349444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella return status_t(NO_ERROR); 350444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } else if (args.size() == 1 && args[0] == String16("enable")) { 351444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // If currently in restricted mode, reset back to NORMAL mode else ignore. 352444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (mCurrentOperatingMode == RESTRICTED) { 353444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella mCurrentOperatingMode = NORMAL; 354444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella dev.enableAllSensors(); 3556c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } 356841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (mCurrentOperatingMode == DATA_INJECTION) { 357841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella resetToNormalModeLocked(); 358841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } 359841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella mWhiteListedPackage.clear(); 360444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella return status_t(NO_ERROR); 361841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } else if (args.size() == 2 && args[0] == String16("data_injection")) { 362841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (mCurrentOperatingMode == NORMAL) { 363841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella dev.disableAllSensors(); 364841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella status_t err = dev.setMode(DATA_INJECTION); 365841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (err == NO_ERROR) { 366841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella mCurrentOperatingMode = DATA_INJECTION; 367841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } else { 368841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella // Re-enable sensors. 369841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella dev.enableAllSensors(); 370841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } 371841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella mWhiteListedPackage.setTo(String8(args[1])); 372841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella return NO_ERROR; 373841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } else if (mCurrentOperatingMode == DATA_INJECTION) { 374841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella // Already in DATA_INJECTION mode. Treat this as a no_op. 375841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella return NO_ERROR; 376841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } else { 377841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella // Transition to data injection mode supported only from NORMAL mode. 378841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella return INVALID_OPERATION; 379841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } 3800cc8f809924706c7d683da30605f432635dd5bb6Peng Xu } else if (!mSensors.hasAnySensor()) { 381ee155cadb23e84542cbf445c2aac89ae63df4cc7Aravind Akella result.append("No Sensors on the device\n"); 382444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } else { 383444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // Default dump the sensor list and debugging information. 3840cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // 3856a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu result.append("Sensor Device:\n"); 3866a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu result.append(SensorDevice::getInstance().dump().c_str()); 3876a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 3886a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu result.append("Sensor List:\n"); 3890cc8f809924706c7d683da30605f432635dd5bb6Peng Xu result.append(mSensors.dump().c_str()); 3906c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 3916a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu result.append("Fusion States:\n"); 392444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella SensorFusion::getInstance().dump(result); 393444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella 3940cc8f809924706c7d683da30605f432635dd5bb6Peng Xu result.append("Recent Sensor events:\n"); 3956a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu for (auto&& i : mRecentEvent) { 3966a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu sp<SensorInterface> s = mSensors.getInterface(i.first); 397fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu if (!i.second->isEmpty()) { 398fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu if (privileged || s->getSensor().getRequiredPermission().isEmpty()) { 399fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu i.second->setFormat("normal"); 400fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu } else { 401fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu i.second->setFormat("mask_data"); 402fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu } 4036a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu // if there is events and sensor does not need special permission. 4046a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu result.appendFormat("%s: ", s->getSensor().getName().string()); 4056a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu result.append(i.second->dump().c_str()); 4066a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu } 4076a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu } 4080cc8f809924706c7d683da30605f432635dd5bb6Peng Xu 409444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.append("Active sensors:\n"); 410444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella for (size_t i=0 ; i<mActiveSensors.size() ; i++) { 411444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella int handle = mActiveSensors.keyAt(i); 412444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat("%s (handle=0x%08x, connections=%zu)\n", 413444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella getSensorName(handle).string(), 414444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella handle, 415444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella mActiveSensors.valueAt(i)->getNumConnections()); 416ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian } 4174c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella 418d4036b6b7f9609fe09efabdbfbb8c8f9428f76f7Andreas Gampe result.appendFormat("Socket Buffer size = %zd events\n", 419444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella mSocketBufferSize/sizeof(sensors_event_t)); 42018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella result.appendFormat("WakeLock Status: %s \n", mWakeLockAcquired ? "acquired" : 42118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella "not held"); 422444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat("Mode :"); 423444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella switch(mCurrentOperatingMode) { 424444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella case NORMAL: 425444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat(" NORMAL\n"); 426444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella break; 427444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella case RESTRICTED: 428841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella result.appendFormat(" RESTRICTED : %s\n", mWhiteListedPackage.string()); 429444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella break; 430444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella case DATA_INJECTION: 431841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella result.appendFormat(" DATA_INJECTION : %s\n", mWhiteListedPackage.string()); 432444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 433444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat("%zd active connections\n", mActiveConnections.size()); 4344c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella 435444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella for (size_t i=0 ; i < mActiveConnections.size() ; i++) { 436444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella sp<SensorEventConnection> connection(mActiveConnections[i].promote()); 437444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (connection != 0) { 438444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat("Connection Number: %zu \n", i); 439444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella connection->dump(result); 440444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 4414c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 44218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella 44318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella result.appendFormat("Previous Registrations:\n"); 44418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella // Log in the reverse chronological order. 44518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella int currentIndex = (mNextSensorRegIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) % 44618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella SENSOR_REGISTRATIONS_BUF_SIZE; 44718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella const int startIndex = currentIndex; 44818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella do { 44918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella const SensorRegistrationInfo& reg_info = mLastNSensorRegistrations[currentIndex]; 45018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella if (SensorRegistrationInfo::isSentinel(reg_info)) { 45118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella // Ignore sentinel, proceed to next item. 45218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella currentIndex = (currentIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) % 45318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella SENSOR_REGISTRATIONS_BUF_SIZE; 45418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella continue; 45518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } 45618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella if (reg_info.mActivated) { 457363b3fde1499521aafdc78d9d28380cc643ec6b5Peng Xu result.appendFormat("%02d:%02d:%02d activated handle=0x%08x " 458363b3fde1499521aafdc78d9d28380cc643ec6b5Peng Xu "samplingRate=%dus maxReportLatency=%dus package=%s\n", 459363b3fde1499521aafdc78d9d28380cc643ec6b5Peng Xu reg_info.mHour, reg_info.mMin, reg_info.mSec, reg_info.mSensorHandle, 460363b3fde1499521aafdc78d9d28380cc643ec6b5Peng Xu reg_info.mSamplingRateUs, reg_info.mMaxReportLatencyUs, 461363b3fde1499521aafdc78d9d28380cc643ec6b5Peng Xu reg_info.mPackageName.string()); 46218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } else { 463363b3fde1499521aafdc78d9d28380cc643ec6b5Peng Xu result.appendFormat("%02d:%02d:%02d de-activated handle=0x%08x package=%s\n", 46418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mHour, reg_info.mMin, reg_info.mSec, 465363b3fde1499521aafdc78d9d28380cc643ec6b5Peng Xu reg_info.mSensorHandle, reg_info.mPackageName.string()); 46618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } 46718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella currentIndex = (currentIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) % 46818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella SENSOR_REGISTRATIONS_BUF_SIZE; 46918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } while(startIndex != currentIndex); 4704c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 471fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 472fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian write(fd, result.string(), result.size()); 473fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return NO_ERROR; 474fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 475fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 4760cc8f809924706c7d683da30605f432635dd5bb6Peng Xu//TODO: move to SensorEventConnection later 4779a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::cleanupAutoDisabledSensorLocked(const sp<SensorEventConnection>& connection, 4784342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh sensors_event_t const* buffer, const int count) { 4794342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh for (int i=0 ; i<count ; i++) { 4804342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh int handle = buffer[i].sensor; 4818493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (buffer[i].type == SENSOR_TYPE_META_DATA) { 4828493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella handle = buffer[i].meta_data.sensor; 4838493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } 4840e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella if (connection->hasSensor(handle)) { 485755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> si = getSensorInterfaceFromHandle(handle); 4860e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella // If this buffer has an event from a one_shot sensor and this connection is registered 4870e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella // for this particular one_shot sensor, try cleaning up the connection. 488755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (si != nullptr && 4890cc8f809924706c7d683da30605f432635dd5bb6Peng Xu si->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) { 4900cc8f809924706c7d683da30605f432635dd5bb6Peng Xu si->autoDisable(connection.get(), handle); 4919a844cf78f09953145200b4074d47589257a408cAravind Akella cleanupWithoutDisableLocked(connection, handle); 4924342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 493a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella 4944342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 495a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella } 4964342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh} 4974342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 49847e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xubool SensorService::threadLoop() { 499a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block ALOGD("nuSensorService thread starting..."); 500fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 501eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // each virtual sensor could generate an event per "real" event, that's why we need to size 502eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT. in practice, this is too 503eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // aggressive, but guaranteed to be enough. 5040cc8f809924706c7d683da30605f432635dd5bb6Peng Xu const size_t vcount = mSensors.getVirtualSensors().size(); 50590ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT; 5060cc8f809924706c7d683da30605f432635dd5bb6Peng Xu const size_t numEventMax = minBufferSize / (1 + vcount); 50790ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian 508f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian SensorDevice& device(SensorDevice::getInstance()); 509fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 5104342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh const int halVersion = device.getHalDeviceVersion(); 511fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian do { 5128493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella ssize_t count = device.poll(mSensorEventBuffer, numEventMax); 5138493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (count < 0) { 514f5a1230d322c14c42331d0a1536b50c87742973bSteve Block ALOGE("sensor poll failed (%s)", strerror(-count)); 515fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian break; 516fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 51756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 51856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // Reset sensors_event_t.flags to zero for all events in the buffer. 51956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella for (int i = 0; i < count; i++) { 5208493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mSensorEventBuffer[i].flags = 0; 52156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 522e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella 523eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // Make a copy of the connection vector as some connections may be removed during the course 524eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // of this loop (especially when one-shot sensor events are present in the sensor_event 525eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // buffer). Promote all connections to StrongPointers before the lock is acquired. If the 526eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // destructor of the sp gets called when the lock is acquired, it may result in a deadlock 527eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // as ~SensorEventConnection() needs to acquire mLock again for cleanup. So copy all the 528eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // strongPointers to a vector before the lock is acquired. 529e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella SortedVector< sp<SensorEventConnection> > activeConnections; 530b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella populateActiveConnections(&activeConnections); 531eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu 5329a844cf78f09953145200b4074d47589257a408cAravind Akella Mutex::Autolock _l(mLock); 5339a844cf78f09953145200b4074d47589257a408cAravind Akella // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The 5349a844cf78f09953145200b4074d47589257a408cAravind Akella // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock, 5359a844cf78f09953145200b4074d47589257a408cAravind Akella // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should 5369a844cf78f09953145200b4074d47589257a408cAravind Akella // not be interleaved with decrementing SensorEventConnection::mWakeLockRefCount and 5379a844cf78f09953145200b4074d47589257a408cAravind Akella // releasing the wakelock. 5389a844cf78f09953145200b4074d47589257a408cAravind Akella bool bufferHasWakeUpEvent = false; 5394342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh for (int i = 0; i < count; i++) { 5408493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (isWakeUpSensorEvent(mSensorEventBuffer[i])) { 5419a844cf78f09953145200b4074d47589257a408cAravind Akella bufferHasWakeUpEvent = true; 5429a844cf78f09953145200b4074d47589257a408cAravind Akella break; 5434342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 5444342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 5454342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 5469a844cf78f09953145200b4074d47589257a408cAravind Akella if (bufferHasWakeUpEvent && !mWakeLockAcquired) { 547b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella setWakeLockAcquiredLocked(true); 5489a844cf78f09953145200b4074d47589257a408cAravind Akella } 5498493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella recordLastValueLocked(mSensorEventBuffer, count); 55094e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian 551f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian // handle virtual sensors 552f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian if (count && vcount) { 5538493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella sensors_event_t const * const event = mSensorEventBuffer; 554755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (!mActiveVirtualSensors.empty()) { 555f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian size_t k = 0; 556984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian SensorFusion& fusion(SensorFusion::getInstance()); 557984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian if (fusion.isEnabled()) { 558984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t i=0 ; i<size_t(count) ; i++) { 559984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian fusion.process(event[i]); 560984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 561984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 562d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) { 563755c451c7861a029e26e5f16e319b629169e656dPeng Xu for (int handle : mActiveVirtualSensors) { 564d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian if (count + k >= minBufferSize) { 565d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian ALOGE("buffer too small to hold all events: " 566db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn "count=%zd, k=%zu, size=%zu", 567d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian count, k, minBufferSize); 568d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian break; 569d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian } 570f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sensors_event_t out; 571755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> si = mSensors.getInterface(handle); 572755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (si == nullptr) { 573755c451c7861a029e26e5f16e319b629169e656dPeng Xu ALOGE("handle %d is not an valid virtual sensor", handle); 574755c451c7861a029e26e5f16e319b629169e656dPeng Xu continue; 575755c451c7861a029e26e5f16e319b629169e656dPeng Xu } 576755c451c7861a029e26e5f16e319b629169e656dPeng Xu 577d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian if (si->process(&out, event[i])) { 5788493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mSensorEventBuffer[count + k] = out; 579f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian k++; 580f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 581f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 582f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 583f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian if (k) { 584f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian // record the last synthesized values 5858493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella recordLastValueLocked(&mSensorEventBuffer[count], k); 586f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian count += k; 587f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian // sort the buffer by time-stamps 5888493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella sortEventBuffer(mSensorEventBuffer, count); 589f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 590f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 591f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 592f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 5934342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // handle backward compatibility for RotationVector sensor 5944342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) { 5954342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh for (int i = 0; i < count; i++) { 5968493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (mSensorEventBuffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) { 5974342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // All the 4 components of the quaternion should be available 5984342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // No heading accuracy. Set it to -1 5998493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mSensorEventBuffer[i].data[4] = -1; 6008493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } 6018493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } 6028493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } 6038493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella 6048493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella for (int i = 0; i < count; ++i) { 6050cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // Map flush_complete_events in the buffer to SensorEventConnections which called flush 6060cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // on the hardware sensor. mapFlushEventsToConnections[i] will be the 6070cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // SensorEventConnection mapped to the corresponding flush_complete_event in 6080cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // mSensorEventBuffer[i] if such a mapping exists (NULL otherwise). 6098493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mMapFlushEventsToConnections[i] = NULL; 6108493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (mSensorEventBuffer[i].type == SENSOR_TYPE_META_DATA) { 6118493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella const int sensor_handle = mSensorEventBuffer[i].meta_data.sensor; 6128493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella SensorRecord* rec = mActiveSensors.valueFor(sensor_handle); 6138493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (rec != NULL) { 6148493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mMapFlushEventsToConnections[i] = rec->getFirstPendingFlushConnection(); 6158493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella rec->removeFirstPendingFlushConnection(); 6164342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 6174342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 6182576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 6192576cb63b3fe1592f54816625036566b9eb0793aPeng Xu // handle dynamic sensor meta events, process registration and unregistration of dynamic 6202576cb63b3fe1592f54816625036566b9eb0793aPeng Xu // sensor based on content of event. 6212576cb63b3fe1592f54816625036566b9eb0793aPeng Xu if (mSensorEventBuffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META) { 6222576cb63b3fe1592f54816625036566b9eb0793aPeng Xu if (mSensorEventBuffer[i].dynamic_sensor_meta.connected) { 6232576cb63b3fe1592f54816625036566b9eb0793aPeng Xu int handle = mSensorEventBuffer[i].dynamic_sensor_meta.handle; 6242576cb63b3fe1592f54816625036566b9eb0793aPeng Xu const sensor_t& dynamicSensor = 6252576cb63b3fe1592f54816625036566b9eb0793aPeng Xu *(mSensorEventBuffer[i].dynamic_sensor_meta.sensor); 6262576cb63b3fe1592f54816625036566b9eb0793aPeng Xu ALOGI("Dynamic sensor handle 0x%x connected, type %d, name %s", 6272576cb63b3fe1592f54816625036566b9eb0793aPeng Xu handle, dynamicSensor.type, dynamicSensor.name); 6282576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 6290cc8f809924706c7d683da30605f432635dd5bb6Peng Xu if (mSensors.isNewHandle(handle)) { 6306a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu const auto& uuid = mSensorEventBuffer[i].dynamic_sensor_meta.uuid; 63147e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu sensor_t s = dynamicSensor; 63247e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu // make sure the dynamic sensor flag is set 63347e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu s.flags |= DYNAMIC_SENSOR_MASK; 63447e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu // force the handle to be consistent 63547e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu s.handle = handle; 6366a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 6376a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu SensorInterface *si = new HardwareSensor(s, uuid); 63847e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu 6390cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // This will release hold on dynamic sensor meta, so it should be called 6400cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // after Sensor object is created. 64147e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu device.handleDynamicSensorConnection(handle, true /*connected*/); 6426a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu registerDynamicSensorLocked(si); 64347e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu } else { 64447e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu ALOGE("Handle %d has been used, cannot use again before reboot.", handle); 64547e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu } 6462576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } else { 6472576cb63b3fe1592f54816625036566b9eb0793aPeng Xu int handle = mSensorEventBuffer[i].dynamic_sensor_meta.handle; 6482576cb63b3fe1592f54816625036566b9eb0793aPeng Xu ALOGI("Dynamic sensor handle 0x%x disconnected", handle); 6492576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 6502576cb63b3fe1592f54816625036566b9eb0793aPeng Xu device.handleDynamicSensorConnection(handle, false /*connected*/); 6516a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu if (!unregisterDynamicSensorLocked(handle)) { 6522576cb63b3fe1592f54816625036566b9eb0793aPeng Xu ALOGE("Dynamic sensor release error."); 6532576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 6542576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 6552576cb63b3fe1592f54816625036566b9eb0793aPeng Xu size_t numConnections = activeConnections.size(); 6562576cb63b3fe1592f54816625036566b9eb0793aPeng Xu for (size_t i=0 ; i < numConnections; ++i) { 6572576cb63b3fe1592f54816625036566b9eb0793aPeng Xu if (activeConnections[i] != NULL) { 6582576cb63b3fe1592f54816625036566b9eb0793aPeng Xu activeConnections[i]->removeSensor(handle); 6592576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 6602576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 6612576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 6622576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 6634342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 6644342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 6652576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 6669a844cf78f09953145200b4074d47589257a408cAravind Akella // Send our events to clients. Check the state of wake lock for each client and release the 6679a844cf78f09953145200b4074d47589257a408cAravind Akella // lock if none of the clients need it. 6689a844cf78f09953145200b4074d47589257a408cAravind Akella bool needsWakeLock = false; 6698493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella size_t numConnections = activeConnections.size(); 6708493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella for (size_t i=0 ; i < numConnections; ++i) { 671e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella if (activeConnections[i] != 0) { 672e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch, 6738493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mMapFlushEventsToConnections); 674e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella needsWakeLock |= activeConnections[i]->needsWakeLock(); 6758493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella // If the connection has one-shot sensors, it may be cleaned up after first trigger. 6768493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella // Early check for one-shot sensors. 677e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella if (activeConnections[i]->hasOneShotSensors()) { 678e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer, 679e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella count); 6808493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } 681fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 682fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 6834342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 6849a844cf78f09953145200b4074d47589257a408cAravind Akella if (mWakeLockAcquired && !needsWakeLock) { 685b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella setWakeLockAcquiredLocked(false); 6869a844cf78f09953145200b4074d47589257a408cAravind Akella } 6878493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } while (!Thread::exitPending()); 688fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 6893c20fbed7f3a916ced10f2ed5a272271b7d81edeSteve Block ALOGW("Exiting SensorService::threadLoop => aborting..."); 6901a62301fc58cd2af18239b0415813461bf5fc41bMathias Agopian abort(); 691fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return false; 692fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 693fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 69456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellasp<Looper> SensorService::getLooper() const { 69556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella return mLooper; 69656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella} 69756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 698b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::resetAllWakeLockRefCounts() { 699b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella SortedVector< sp<SensorEventConnection> > activeConnections; 700b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella populateActiveConnections(&activeConnections); 701b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella { 702b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella Mutex::Autolock _l(mLock); 703b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella for (size_t i=0 ; i < activeConnections.size(); ++i) { 704b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (activeConnections[i] != 0) { 705b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella activeConnections[i]->resetWakeLockRefCount(); 706b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 707b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 708b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella setWakeLockAcquiredLocked(false); 709b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 710b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella} 711b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella 712b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::setWakeLockAcquiredLocked(bool acquire) { 713b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (acquire) { 714b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (!mWakeLockAcquired) { 715b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME); 716b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mWakeLockAcquired = true; 717b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 718b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mLooper->wake(); 719b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } else { 720b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (mWakeLockAcquired) { 721b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella release_wake_lock(WAKE_LOCK_NAME); 722b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mWakeLockAcquired = false; 723b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 724b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 725b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella} 726b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella 727b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellabool SensorService::isWakeLockAcquired() { 728b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella Mutex::Autolock _l(mLock); 729b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella return mWakeLockAcquired; 730b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella} 731b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella 73256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellabool SensorService::SensorEventAckReceiver::threadLoop() { 73356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella ALOGD("new thread SensorEventAckReceiver"); 734b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella sp<Looper> looper = mService->getLooper(); 73556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella do { 736b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella bool wakeLockAcquired = mService->isWakeLockAcquired(); 737b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella int timeout = -1; 738b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (wakeLockAcquired) timeout = 5000; 739b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella int ret = looper->pollOnce(timeout); 740b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (ret == ALOOPER_POLL_TIMEOUT) { 741b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mService->resetAllWakeLockRefCounts(); 742b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 74356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } while(!Thread::exitPending()); 74456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella return false; 74556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella} 74656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 7479a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::recordLastValueLocked( 7484b84704b97300eff3ebfab85652e64d54149d205Aravind Akella const sensors_event_t* buffer, size_t count) { 7494b84704b97300eff3ebfab85652e64d54149d205Aravind Akella for (size_t i = 0; i < count; i++) { 7502576cb63b3fe1592f54816625036566b9eb0793aPeng Xu if (buffer[i].type == SENSOR_TYPE_META_DATA || 7512576cb63b3fe1592f54816625036566b9eb0793aPeng Xu buffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META || 7526a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO) { 7532576cb63b3fe1592f54816625036566b9eb0793aPeng Xu continue; 7542576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 7552576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 7566a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu auto logger = mRecentEvent.find(buffer[i].sensor); 7576a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu if (logger != mRecentEvent.end()) { 7586a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu logger->second->addEvent(buffer[i]); 75994e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian } 76094e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian } 76194e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian} 76294e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian 76347e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xuvoid SensorService::sortEventBuffer(sensors_event_t* buffer, size_t count) { 764f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian struct compar { 765f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian static int cmp(void const* lhs, void const* rhs) { 766f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sensors_event_t const* l = static_cast<sensors_event_t const*>(lhs); 767f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sensors_event_t const* r = static_cast<sensors_event_t const*>(rhs); 768a5c106a4f0afcf061728a1cb7c8c3b908728575dMathias Agopian return l->timestamp - r->timestamp; 769f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 770f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian }; 771f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian qsort(buffer, count, sizeof(sensors_event_t), compar::cmp); 772f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian} 773f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 7745d2707214dfb97bd8dfcc6620be36841d3c82420Mathias AgopianString8 SensorService::getSensorName(int handle) const { 7750cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return mSensors.getName(handle); 7765d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian} 7775d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian 778b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akellabool SensorService::isVirtualSensor(int handle) const { 779755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 780755c451c7861a029e26e5f16e319b629169e656dPeng Xu return sensor != nullptr && sensor->isVirtual(); 781b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella} 782b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella 7839a844cf78f09953145200b4074d47589257a408cAravind Akellabool SensorService::isWakeUpSensorEvent(const sensors_event_t& event) const { 7847869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan int handle = event.sensor; 7857869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan if (event.type == SENSOR_TYPE_META_DATA) { 7867869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan handle = event.meta_data.sensor; 7877869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan } 788755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 789755c451c7861a029e26e5f16e319b629169e656dPeng Xu return sensor != nullptr && sensor->getSensor().isWakeUpSensor(); 7909a844cf78f09953145200b4074d47589257a408cAravind Akella} 7919a844cf78f09953145200b4074d47589257a408cAravind Akella 79253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiserint32_t SensorService::getIdFromUuid(const Sensor::uuid_t &uuid) const { 79353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if ((uuid.i64[0] == 0) && (uuid.i64[1] == 0)) { 79453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // UUID is not supported for this device. 79553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return 0; 79653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 79753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if ((uuid.i64[0] == INT64_C(~0)) && (uuid.i64[1] == INT64_C(~0))) { 79853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // This sensor can be uniquely identified in the system by 79953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // the combination of its type and name. 80053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return -1; 80153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 80253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 80353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // We have a dynamic sensor. 80453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 80553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (!sHmacGlobalKeyIsValid) { 80653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Rather than risk exposing UUIDs, we cripple dynamic sensors. 80753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser ALOGW("HMAC key failure; dynamic sensor getId() will be wrong."); 80853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return 0; 80953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 81053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 81153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // We want each app author/publisher to get a different ID, so that the 81253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // same dynamic sensor cannot be tracked across apps by multiple 81353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // authors/publishers. So we use both our UUID and our User ID. 81453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Note potential confusion: 81553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // UUID => Universally Unique Identifier. 81653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // UID => User Identifier. 81753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // We refrain from using "uid" except as needed by API to try to 81853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // keep this distinction clear. 81953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 82053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser auto appUserId = IPCThreadState::self()->getCallingUid(); 82153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser uint8_t uuidAndApp[sizeof(uuid) + sizeof(appUserId)]; 82253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser memcpy(uuidAndApp, &uuid, sizeof(uuid)); 82353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser memcpy(uuidAndApp + sizeof(uuid), &appUserId, sizeof(appUserId)); 82453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 82553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Now we use our key on our UUID/app combo to get the hash. 82653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser uint8_t hash[EVP_MAX_MD_SIZE]; 82753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser unsigned int hashLen; 82853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (HMAC(EVP_sha256(), 82953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser sHmacGlobalKey, sizeof(sHmacGlobalKey), 83053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser uuidAndApp, sizeof(uuidAndApp), 83153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser hash, &hashLen) == nullptr) { 83253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Rather than risk exposing UUIDs, we cripple dynamic sensors. 83353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser ALOGW("HMAC failure; dynamic sensor getId() will be wrong."); 83453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return 0; 83553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 83653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 83753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser int32_t id = 0; 83853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (hashLen < sizeof(id)) { 83953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // We never expect this case, but out of paranoia, we handle it. 84053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Our 'id' length is already quite small, we don't want the 84153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // effective length of it to be even smaller. 84253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Rather than risk exposing UUIDs, we cripple dynamic sensors. 84353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser ALOGW("HMAC insufficient; dynamic sensor getId() will be wrong."); 84453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return 0; 84553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 84653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 84753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // This is almost certainly less than all of 'hash', but it's as secure 84853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // as we can be with our current 'id' length. 84953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser memcpy(&id, hash, sizeof(id)); 85053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 85153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Note at the beginning of the function that we return the values of 85253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // 0 and -1 to represent special cases. As a result, we can't return 85353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // those as dynamic sensor IDs. If we happened to hash to one of those 85453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // values, we change 'id' so we report as a dynamic sensor, and not as 85553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // one of those special cases. 85653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (id == -1) { 85753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser id = -2; 85853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } else if (id == 0) { 85953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser id = 1; 86053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 86153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return id; 86253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser} 86353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 86453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiservoid SensorService::makeUuidsIntoIdsForSensorList(Vector<Sensor> &sensorList) const { 86553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser for (auto &sensor : sensorList) { 86653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser int32_t id = getIdFromUuid(sensor.getUuid()); 86753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser sensor.setId(id); 86853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 86953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser} 87053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 8712c588c536090ea3e7e80db0e5031935b6026814cNick VaccaroVector<Sensor> SensorService::getSensorList(const String16& /* opPackageName */) { 87233264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian char value[PROPERTY_VALUE_MAX]; 87333264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian property_get("debug.sensors", value, "0"); 874700180487ffec09d9df1657b018a7caadac24b75Aravind Akella const Vector<Sensor>& initialSensorList = (atoi(value)) ? 8750cc8f809924706c7d683da30605f432635dd5bb6Peng Xu mSensors.getUserDebugSensors() : mSensors.getUserSensors(); 876700180487ffec09d9df1657b018a7caadac24b75Aravind Akella Vector<Sensor> accessibleSensorList; 877700180487ffec09d9df1657b018a7caadac24b75Aravind Akella for (size_t i = 0; i < initialSensorList.size(); i++) { 878700180487ffec09d9df1657b018a7caadac24b75Aravind Akella Sensor sensor = initialSensorList[i]; 8792c588c536090ea3e7e80db0e5031935b6026814cNick Vaccaro accessibleSensorList.add(sensor); 88033264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian } 88153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser makeUuidsIntoIdsForSensorList(accessibleSensorList); 882700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return accessibleSensorList; 883fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 884fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 88547e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng XuVector<Sensor> SensorService::getDynamicSensorList(const String16& opPackageName) { 8862576cb63b3fe1592f54816625036566b9eb0793aPeng Xu Vector<Sensor> accessibleSensorList; 8870cc8f809924706c7d683da30605f432635dd5bb6Peng Xu mSensors.forEachSensor( 8880cc8f809924706c7d683da30605f432635dd5bb6Peng Xu [&opPackageName, &accessibleSensorList] (const Sensor& sensor) -> bool { 889755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (sensor.isDynamicSensor()) { 890755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (canAccessSensor(sensor, "getDynamicSensorList", opPackageName)) { 891755c451c7861a029e26e5f16e319b629169e656dPeng Xu accessibleSensorList.add(sensor); 892755c451c7861a029e26e5f16e319b629169e656dPeng Xu } else { 893755c451c7861a029e26e5f16e319b629169e656dPeng Xu ALOGI("Skipped sensor %s because it requires permission %s and app op %" PRId32, 894755c451c7861a029e26e5f16e319b629169e656dPeng Xu sensor.getName().string(), 895755c451c7861a029e26e5f16e319b629169e656dPeng Xu sensor.getRequiredPermission().string(), 896755c451c7861a029e26e5f16e319b629169e656dPeng Xu sensor.getRequiredAppOp()); 897755c451c7861a029e26e5f16e319b629169e656dPeng Xu } 8980cc8f809924706c7d683da30605f432635dd5bb6Peng Xu } 8990cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return true; 9000cc8f809924706c7d683da30605f432635dd5bb6Peng Xu }); 90153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser makeUuidsIntoIdsForSensorList(accessibleSensorList); 9022576cb63b3fe1592f54816625036566b9eb0793aPeng Xu return accessibleSensorList; 9032576cb63b3fe1592f54816625036566b9eb0793aPeng Xu} 9042576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 905a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellasp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName, 906b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav int requestedMode, const String16& opPackageName) { 907a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella // Only 2 modes supported for a SensorEventConnection ... NORMAL and DATA_INJECTION. 908a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella if (requestedMode != NORMAL && requestedMode != DATA_INJECTION) { 909a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella return NULL; 910a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella } 911a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella 912a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella Mutex::Autolock _l(mLock); 913841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella // To create a client in DATA_INJECTION mode to inject data, SensorService should already be 914841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella // operating in DI mode. 915841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (requestedMode == DATA_INJECTION) { 916841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (mCurrentOperatingMode != DATA_INJECTION) return NULL; 917841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (!isWhiteListedPackage(packageName)) return NULL; 918841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } 919841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella 9205307d17fe33fc26eeeacd6339a9fbfe96cf56873Mathias Agopian uid_t uid = IPCThreadState::self()->getCallingUid(); 921a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella sp<SensorEventConnection> result(new SensorEventConnection(this, uid, packageName, 922b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav requestedMode == DATA_INJECTION, opPackageName)); 923a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella if (requestedMode == DATA_INJECTION) { 924a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella if (mActiveConnections.indexOf(result) < 0) { 925a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella mActiveConnections.add(result); 926a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella } 927a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella // Add the associated file descriptor to the Looper for polling whenever there is data to 928a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella // be injected. 929a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella result->updateLooperRegistration(mLooper); 930a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella } 931fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return result; 932fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 933fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 934841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akellaint SensorService::isDataInjectionEnabled() { 935a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella Mutex::Autolock _l(mLock); 936841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella return (mCurrentOperatingMode == DATA_INJECTION); 937a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella} 938a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella 939a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatus_t SensorService::resetToNormalMode() { 940a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella Mutex::Autolock _l(mLock); 941a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella return resetToNormalModeLocked(); 942a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella} 943a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella 944a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatus_t SensorService::resetToNormalModeLocked() { 945a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella SensorDevice& dev(SensorDevice::getInstance()); 946a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella status_t err = dev.setMode(NORMAL); 947bfac17eed90d410de51413ef2484f79fb0e241e2Aniroop Mathur if (err == NO_ERROR) { 948bfac17eed90d410de51413ef2484f79fb0e241e2Aniroop Mathur mCurrentOperatingMode = NORMAL; 949bfac17eed90d410de51413ef2484f79fb0e241e2Aniroop Mathur dev.enableAllSensors(); 950bfac17eed90d410de51413ef2484f79fb0e241e2Aniroop Mathur } 951a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella return err; 952a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella} 953a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella 95447e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xuvoid SensorService::cleanupConnection(SensorEventConnection* c) { 955fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian Mutex::Autolock _l(mLock); 956db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian const wp<SensorEventConnection> connection(c); 9577c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian size_t size = mActiveSensors.size(); 958db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn ALOGD_IF(DEBUG_CONNECTIONS, "%zu active sensors", size); 9597c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian for (size_t i=0 ; i<size ; ) { 960db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian int handle = mActiveSensors.keyAt(i); 961db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian if (c->hasSensor(handle)) { 962db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn ALOGD_IF(DEBUG_CONNECTIONS, "%zu: disabling handle=0x%08x", i, handle); 963755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 964755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (sensor != nullptr) { 965db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian sensor->activate(c, false); 966755c451c7861a029e26e5f16e319b629169e656dPeng Xu } else { 967755c451c7861a029e26e5f16e319b629169e656dPeng Xu ALOGE("sensor interface of handle=0x%08x is null!", handle); 968f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 9698a96955c8e14db40b16164236830fc9506a00872Aravind Akella c->removeSensor(handle); 970db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian } 971db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian SensorRecord* rec = mActiveSensors.valueAt(i); 972db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn ALOGE_IF(!rec, "mActiveSensors[%zu] is null (handle=0x%08x)!", i, handle); 973a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block ALOGD_IF(DEBUG_CONNECTIONS, 974db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn "removing connection %p for sensor[%zu].handle=0x%08x", 975a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian c, i, handle); 976a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian 977db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian if (rec && rec->removeConnection(connection)) { 978a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block ALOGD_IF(DEBUG_CONNECTIONS, "... and it was the last connection"); 9797c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian mActiveSensors.removeItemsAt(i, 1); 980755c451c7861a029e26e5f16e319b629169e656dPeng Xu mActiveVirtualSensors.erase(handle); 9817c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian delete rec; 9827c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian size--; 9837c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian } else { 9847c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian i++; 985fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 986fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 9878a96955c8e14db40b16164236830fc9506a00872Aravind Akella c->updateLooperRegistration(mLooper); 9887c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian mActiveConnections.remove(connection); 989787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian BatteryService::cleanup(c->getUid()); 9909a844cf78f09953145200b4074d47589257a408cAravind Akella if (c->needsWakeLock()) { 9919a844cf78f09953145200b4074d47589257a408cAravind Akella checkWakeLockStateLocked(); 9929a844cf78f09953145200b4074d47589257a408cAravind Akella } 9934f707f8b3da68d3055db895da9ae5216cc4f483aPeng Xu 9944f707f8b3da68d3055db895da9ae5216cc4f483aPeng Xu SensorDevice& dev(SensorDevice::getInstance()); 9954f707f8b3da68d3055db895da9ae5216cc4f483aPeng Xu dev.notifyConnectionDestroyed(c); 996fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 997fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 998755c451c7861a029e26e5f16e319b629169e656dPeng Xusp<SensorInterface> SensorService::getSensorInterfaceFromHandle(int handle) const { 9990cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return mSensors.getInterface(handle); 100047e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu} 100147e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu 1002700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 1003fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::enable(const sp<SensorEventConnection>& connection, 1004b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags, 100547e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu const String16& opPackageName) { 100650df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian if (mInitCheck != NO_ERROR) 100750df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian return mInitCheck; 100850df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian 1009755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 1010755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (sensor == nullptr || 1011755c451c7861a029e26e5f16e319b629169e656dPeng Xu !canAccessSensor(sensor->getSensor(), "Tried enabling", opPackageName)) { 1012700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return BAD_VALUE; 1013700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } 1014700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 1015ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian Mutex::Autolock _l(mLock); 1016841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if ((mCurrentOperatingMode == RESTRICTED || mCurrentOperatingMode == DATA_INJECTION) 1017841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella && !isWhiteListedPackage(connection->getPackageName())) { 10184949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella return INVALID_OPERATION; 10194949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella } 10204949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella 10214342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh SensorRecord* rec = mActiveSensors.valueFor(handle); 10224342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (rec == 0) { 10234342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh rec = new SensorRecord(connection); 10244342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh mActiveSensors.add(handle, rec); 10254342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (sensor->isVirtual()) { 1026755c451c7861a029e26e5f16e319b629169e656dPeng Xu mActiveVirtualSensors.emplace(handle); 10273560fb24b668675627934356f210d84d19bf4e56Mathias Agopian } 10284342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } else { 10294342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (rec->addConnection(connection)) { 10309a844cf78f09953145200b4074d47589257a408cAravind Akella // this sensor is already activated, but we are adding a connection that uses it. 10319a844cf78f09953145200b4074d47589257a408cAravind Akella // Immediately send down the last known value of the requested sensor if it's not a 10324342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // "continuous" sensor. 10330e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ON_CHANGE) { 10349a844cf78f09953145200b4074d47589257a408cAravind Akella // NOTE: The wake_up flag of this event may get set to 10359a844cf78f09953145200b4074d47589257a408cAravind Akella // WAKE_UP_SENSOR_EVENT_NEEDS_ACK if this is a wake_up event. 10366a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 10376a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu auto logger = mRecentEvent.find(handle); 10386a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu if (logger != mRecentEvent.end()) { 1039444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella sensors_event_t event; 1040444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // It is unlikely that this buffer is empty as the sensor is already active. 1041444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // One possible corner case may be two applications activating an on-change 1042444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // sensor at the same time. 10436a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu if(logger->second->populateLastEvent(&event)) { 1044444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella event.sensor = handle; 1045444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (event.version == sizeof(sensors_event_t)) { 1046444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (isWakeUpSensorEvent(event) && !mWakeLockAcquired) { 1047444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella setWakeLockAcquiredLocked(true); 1048444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 1049444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella connection->sendEvents(&event, 1, NULL); 1050444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (!connection->needsWakeLock() && mWakeLockAcquired) { 1051444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella checkWakeLockStateLocked(); 1052444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 1053444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 10549a844cf78f09953145200b4074d47589257a408cAravind Akella } 1055f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 10567c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian } 1057fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 1058fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 10594342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 10604342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (connection->addSensor(handle)) { 10614342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh BatteryService::enableSensor(connection->getUid(), handle); 10624342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // the sensor was added (which means it wasn't already there) 10634342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // so, see if this connection becomes active 10644342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (mActiveConnections.indexOf(connection) < 0) { 10654342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh mActiveConnections.add(connection); 10664342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 10674342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } else { 10684342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh ALOGW("sensor %08x already enabled in connection %p (ignoring)", 10694342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh handle, connection.get()); 10704342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 10714342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 1072724d91d778e71c8186399f4955de14b54812b3edAravind Akella nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs(); 1073724d91d778e71c8186399f4955de14b54812b3edAravind Akella if (samplingPeriodNs < minDelayNs) { 1074724d91d778e71c8186399f4955de14b54812b3edAravind Akella samplingPeriodNs = minDelayNs; 1075724d91d778e71c8186399f4955de14b54812b3edAravind Akella } 1076724d91d778e71c8186399f4955de14b54812b3edAravind Akella 10776c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d" 10786c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella "rate=%" PRId64 " timeout== %" PRId64"", 1079724d91d778e71c8186399f4955de14b54812b3edAravind Akella handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs); 1080724d91d778e71c8186399f4955de14b54812b3edAravind Akella 10814949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella status_t err = sensor->batch(connection.get(), handle, 0, samplingPeriodNs, 1082724d91d778e71c8186399f4955de14b54812b3edAravind Akella maxBatchReportLatencyNs); 10836c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 108420483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // Call flush() before calling activate() on the sensor. Wait for a first 108520483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // flush complete event before sending events on this connection. Ignore 108620483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // one-shot sensors which don't support flush(). Ignore on-change sensors 108720483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // to maintain the on-change logic (any on-change events except the initial 108820483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // one should be trigger by a change in value). Also if this sensor isn't 108920483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // already active, don't call flush(). 109020483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu if (err == NO_ERROR && 10912576cb63b3fe1592f54816625036566b9eb0793aPeng Xu sensor->getSensor().getReportingMode() == AREPORTING_MODE_CONTINUOUS && 10925466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella rec->getNumConnections() > 1) { 10935466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella connection->setFirstFlushPending(handle, true); 10944c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella status_t err_flush = sensor->flush(connection.get(), handle); 10955466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // Flush may return error if the underlying h/w sensor uses an older HAL. 10966c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella if (err_flush == NO_ERROR) { 10976c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella rec->addPendingFlushConnection(connection.get()); 10985466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella } else { 10995466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella connection->setFirstFlushPending(handle, false); 11004c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 11014c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 1102724d91d778e71c8186399f4955de14b54812b3edAravind Akella 1103724d91d778e71c8186399f4955de14b54812b3edAravind Akella if (err == NO_ERROR) { 1104724d91d778e71c8186399f4955de14b54812b3edAravind Akella ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle); 1105724d91d778e71c8186399f4955de14b54812b3edAravind Akella err = sensor->activate(connection.get(), true); 1106724d91d778e71c8186399f4955de14b54812b3edAravind Akella } 1107724d91d778e71c8186399f4955de14b54812b3edAravind Akella 11088a96955c8e14db40b16164236830fc9506a00872Aravind Akella if (err == NO_ERROR) { 11098a96955c8e14db40b16164236830fc9506a00872Aravind Akella connection->updateLooperRegistration(mLooper); 111018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella SensorRegistrationInfo ®_info = 111118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex); 111218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mSensorHandle = handle; 111318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mSamplingRateUs = samplingPeriodNs/1000; 111418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mMaxReportLatencyUs = maxBatchReportLatencyNs/1000; 111518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mActivated = true; 111618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mPackageName = connection->getPackageName(); 111718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella time_t rawtime = time(NULL); 111818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella struct tm * timeinfo = localtime(&rawtime); 111918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mHour = timeinfo->tm_hour; 112018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mMin = timeinfo->tm_min; 112118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mSec = timeinfo->tm_sec; 112218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mNextSensorRegIndex = (mNextSensorRegIndex + 1) % SENSOR_REGISTRATIONS_BUF_SIZE; 112356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 112456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 11254342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (err != NO_ERROR) { 1126724d91d778e71c8186399f4955de14b54812b3edAravind Akella // batch/activate has failed, reset our state. 1127ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian cleanupWithoutDisableLocked(connection, handle); 11284342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 1129fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return err; 1130fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 1131fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 113247e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xustatus_t SensorService::disable(const sp<SensorEventConnection>& connection, int handle) { 113350df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian if (mInitCheck != NO_ERROR) 113450df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian return mInitCheck; 113550df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian 1136ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian Mutex::Autolock _l(mLock); 1137ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian status_t err = cleanupWithoutDisableLocked(connection, handle); 11384342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (err == NO_ERROR) { 1139755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 1140755c451c7861a029e26e5f16e319b629169e656dPeng Xu err = sensor != nullptr ? sensor->activate(connection.get(), false) : status_t(BAD_VALUE); 114118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella 114218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } 114318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella if (err == NO_ERROR) { 114418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella SensorRegistrationInfo ®_info = 114518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex); 114618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mActivated = false; 114718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mPackageName= connection->getPackageName(); 114818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mSensorHandle = handle; 114918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella time_t rawtime = time(NULL); 115018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella struct tm * timeinfo = localtime(&rawtime); 115118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mHour = timeinfo->tm_hour; 115218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mMin = timeinfo->tm_min; 115318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella reg_info.mSec = timeinfo->tm_sec; 115418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mNextSensorRegIndex = (mNextSensorRegIndex + 1) % SENSOR_REGISTRATIONS_BUF_SIZE; 11554342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 11564342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh return err; 11574342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh} 11584342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 1159ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisable( 1160ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian const sp<SensorEventConnection>& connection, int handle) { 1161fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian Mutex::Autolock _l(mLock); 1162ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian return cleanupWithoutDisableLocked(connection, handle); 1163ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian} 1164ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian 1165ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisableLocked( 1166ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian const sp<SensorEventConnection>& connection, int handle) { 1167fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian SensorRecord* rec = mActiveSensors.valueFor(handle); 1168fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian if (rec) { 1169fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian // see if this connection becomes inactive 1170787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian if (connection->removeSensor(handle)) { 1171787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian BatteryService::disableSensor(connection->getUid(), handle); 1172787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian } 1173fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian if (connection->hasAnySensor() == false) { 11748a96955c8e14db40b16164236830fc9506a00872Aravind Akella connection->updateLooperRegistration(mLooper); 1175fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian mActiveConnections.remove(connection); 1176fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 1177fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian // see if this sensor becomes inactive 1178fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian if (rec->removeConnection(connection)) { 1179fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian mActiveSensors.removeItem(handle); 1180755c451c7861a029e26e5f16e319b629169e656dPeng Xu mActiveVirtualSensors.erase(handle); 1181fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian delete rec; 1182fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 11834342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh return NO_ERROR; 11847c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian } 11854342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh return BAD_VALUE; 1186fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 1187fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 11887c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianstatus_t SensorService::setEventRate(const sp<SensorEventConnection>& connection, 118947e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu int handle, nsecs_t ns, const String16& opPackageName) { 119050df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian if (mInitCheck != NO_ERROR) 119150df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian return mInitCheck; 119250df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian 1193755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 1194755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (sensor == nullptr || 1195755c451c7861a029e26e5f16e319b629169e656dPeng Xu !canAccessSensor(sensor->getSensor(), "Tried configuring", opPackageName)) { 1196700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return BAD_VALUE; 1197700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } 1198700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 11991cd700015318727d6d42236ab6274f1949fb08baMathias Agopian if (ns < 0) 12001cd700015318727d6d42236ab6274f1949fb08baMathias Agopian return BAD_VALUE; 12011cd700015318727d6d42236ab6274f1949fb08baMathias Agopian 120262569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs(); 120362569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian if (ns < minDelayNs) { 120462569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian ns = minDelayNs; 1205ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian } 1206ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian 1207f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian return sensor->setDelay(connection.get(), handle, ns); 1208fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 1209fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 1210b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslavstatus_t SensorService::flushSensor(const sp<SensorEventConnection>& connection, 1211b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav const String16& opPackageName) { 1212700180487ffec09d9df1657b018a7caadac24b75Aravind Akella if (mInitCheck != NO_ERROR) return mInitCheck; 12139e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella SensorDevice& dev(SensorDevice::getInstance()); 12149e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella const int halVersion = dev.getHalDeviceVersion(); 12159e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella status_t err(NO_ERROR); 12169e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella Mutex::Autolock _l(mLock); 12179e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // Loop through all sensors for this connection and call flush on each of them. 12189e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella for (size_t i = 0; i < connection->mSensorInfo.size(); ++i) { 12199e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella const int handle = connection->mSensorInfo.keyAt(i); 1220755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 1221755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (sensor == nullptr) { 1222755c451c7861a029e26e5f16e319b629169e656dPeng Xu continue; 1223755c451c7861a029e26e5f16e319b629169e656dPeng Xu } 12249e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) { 12259e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella ALOGE("flush called on a one-shot sensor"); 12269e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella err = INVALID_OPERATION; 12279e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella continue; 12289e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } 12298493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (halVersion <= SENSORS_DEVICE_API_VERSION_1_0 || isVirtualSensor(handle)) { 12309e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // For older devices just increment pending flush count which will send a trivial 12319e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // flush complete event. 12328a96955c8e14db40b16164236830fc9506a00872Aravind Akella connection->incrementPendingFlushCount(handle); 12339e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } else { 1234b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (!canAccessSensor(sensor->getSensor(), "Tried flushing", opPackageName)) { 1235b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav err = INVALID_OPERATION; 1236b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav continue; 1237b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav } 12389e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella status_t err_flush = sensor->flush(connection.get(), handle); 12399e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella if (err_flush == NO_ERROR) { 12409e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella SensorRecord* rec = mActiveSensors.valueFor(handle); 12419e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella if (rec != NULL) rec->addPendingFlushConnection(connection); 12429e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } 12439e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella err = (err_flush != NO_ERROR) ? err_flush : err; 12449e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } 12456c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } 12469e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella return err; 1247700180487ffec09d9df1657b018a7caadac24b75Aravind Akella} 1248700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 1249b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslavbool SensorService::canAccessSensor(const Sensor& sensor, const char* operation, 1250b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav const String16& opPackageName) { 1251b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav const String8& requiredPermission = sensor.getRequiredPermission(); 1252700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 1253b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (requiredPermission.length() <= 0) { 1254700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return true; 1255b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav } 1256b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav 1257b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav bool hasPermission = false; 1258b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav 1259b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav // Runtime permissions can't use the cache as they may change. 1260b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (sensor.isRequiredPermissionRuntime()) { 1261b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav hasPermission = checkPermission(String16(requiredPermission), 1262b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav IPCThreadState::self()->getCallingPid(), IPCThreadState::self()->getCallingUid()); 1263700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } else { 1264b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav hasPermission = PermissionCache::checkCallingPermission(String16(requiredPermission)); 1265b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav } 1266b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav 1267b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (!hasPermission) { 1268b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav ALOGE("%s a sensor (%s) without holding its required permission: %s", 1269b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav operation, sensor.getName().string(), sensor.getRequiredPermission().string()); 1270700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return false; 1271700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } 1272b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav 1273b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav const int32_t opCode = sensor.getRequiredAppOp(); 1274b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (opCode >= 0) { 1275b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav AppOpsManager appOps; 1276b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (appOps.noteOp(opCode, IPCThreadState::self()->getCallingUid(), opPackageName) 1277b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav != AppOpsManager::MODE_ALLOWED) { 1278d4036b6b7f9609fe09efabdbfbb8c8f9428f76f7Andreas Gampe ALOGE("%s a sensor (%s) without enabled required app op: %d", 1279b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav operation, sensor.getName().string(), opCode); 1280b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav return false; 1281b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav } 1282b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav } 1283b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav 1284b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav return true; 1285700180487ffec09d9df1657b018a7caadac24b75Aravind Akella} 1286700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 12879a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockState() { 12889a844cf78f09953145200b4074d47589257a408cAravind Akella Mutex::Autolock _l(mLock); 12899a844cf78f09953145200b4074d47589257a408cAravind Akella checkWakeLockStateLocked(); 12909a844cf78f09953145200b4074d47589257a408cAravind Akella} 12919a844cf78f09953145200b4074d47589257a408cAravind Akella 12929a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockStateLocked() { 12939a844cf78f09953145200b4074d47589257a408cAravind Akella if (!mWakeLockAcquired) { 12949a844cf78f09953145200b4074d47589257a408cAravind Akella return; 12959a844cf78f09953145200b4074d47589257a408cAravind Akella } 12969a844cf78f09953145200b4074d47589257a408cAravind Akella bool releaseLock = true; 12979a844cf78f09953145200b4074d47589257a408cAravind Akella for (size_t i=0 ; i<mActiveConnections.size() ; i++) { 12989a844cf78f09953145200b4074d47589257a408cAravind Akella sp<SensorEventConnection> connection(mActiveConnections[i].promote()); 12999a844cf78f09953145200b4074d47589257a408cAravind Akella if (connection != 0) { 13009a844cf78f09953145200b4074d47589257a408cAravind Akella if (connection->needsWakeLock()) { 13019a844cf78f09953145200b4074d47589257a408cAravind Akella releaseLock = false; 13029a844cf78f09953145200b4074d47589257a408cAravind Akella break; 13039a844cf78f09953145200b4074d47589257a408cAravind Akella } 13049a844cf78f09953145200b4074d47589257a408cAravind Akella } 13059a844cf78f09953145200b4074d47589257a408cAravind Akella } 13069a844cf78f09953145200b4074d47589257a408cAravind Akella if (releaseLock) { 1307b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella setWakeLockAcquiredLocked(false); 1308b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 1309b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella} 1310b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella 1311b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::sendEventsFromCache(const sp<SensorEventConnection>& connection) { 1312b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella Mutex::Autolock _l(mLock); 1313b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella connection->writeToSocketFromCache(); 1314b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (connection->needsWakeLock()) { 1315b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella setWakeLockAcquiredLocked(true); 1316b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 1317b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella} 1318b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella 1319b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::populateActiveConnections( 1320b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella SortedVector< sp<SensorEventConnection> >* activeConnections) { 1321b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella Mutex::Autolock _l(mLock); 1322b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella for (size_t i=0 ; i < mActiveConnections.size(); ++i) { 1323b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella sp<SensorEventConnection> connection(mActiveConnections[i].promote()); 1324b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (connection != 0) { 1325b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella activeConnections->add(connection); 1326b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 13279a844cf78f09953145200b4074d47589257a408cAravind Akella } 13289a844cf78f09953145200b4074d47589257a408cAravind Akella} 13296c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 13304949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akellabool SensorService::isWhiteListedPackage(const String8& packageName) { 1331841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella return (packageName.contains(mWhiteListedPackage.string())); 13324949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella} 13334949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella 1334fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}; // namespace android 1335fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 1336