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 */ 16b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav#include <binder/AppOpsManager.h> 17fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <binder/BinderService.h> 18451beee076cac09f817abae78a990dea108a9482Mathias Agopian#include <binder/IServiceManager.h> 191cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian#include <binder/PermissionCache.h> 20e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu#include <cutils/ashmem.h> 21dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu#include <cutils/properties.h> 22fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <hardware/sensors.h> 234342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh#include <hardware_legacy/power.h> 248b1517ced6a294f479e261961d03c7356dec0838Brian Duddie#include <log/log.h> 2553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <openssl/digest.h> 2653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <openssl/hmac.h> 2753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <openssl/rand.h> 28dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu#include <sensor/SensorEventQueue.h> 29dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu#include <utils/SystemClock.h> 3053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 31787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian#include "BatteryService.h" 32984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "CorrectedGyroSensor.h" 33f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "GravitySensor.h" 34f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "LinearAccelerationSensor.h" 35984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "OrientationSensor.h" 36f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "RotationVectorSensor.h" 37984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "SensorFusion.h" 38755c451c7861a029e26e5f16e319b629169e656dPeng Xu#include "SensorInterface.h" 39eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu 40984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "SensorService.h" 41e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu#include "SensorDirectConnection.h" 42eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include "SensorEventAckReceiver.h" 436a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu#include "SensorEventConnection.h" 44eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include "SensorRecord.h" 45eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include "SensorRegistrationInfo.h" 46eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu 47eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <inttypes.h> 48eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <math.h> 4998d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu#include <sched.h> 50eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <stdint.h> 51eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <sys/socket.h> 5253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <sys/stat.h> 5353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <sys/types.h> 5453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <unistd.h> 55fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 56fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopiannamespace android { 57fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// --------------------------------------------------------------------------- 58fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 593301542828febc768e1df42892cfac4992c35474Mathias Agopian/* 603301542828febc768e1df42892cfac4992c35474Mathias Agopian * Notes: 613301542828febc768e1df42892cfac4992c35474Mathias Agopian * 623301542828febc768e1df42892cfac4992c35474Mathias Agopian * - what about a gyro-corrected magnetic-field sensor? 633301542828febc768e1df42892cfac4992c35474Mathias Agopian * - run mag sensor from time to time to force calibration 643301542828febc768e1df42892cfac4992c35474Mathias Agopian * - gravity sensor length is wrong (=> drift in linear-acc sensor) 653301542828febc768e1df42892cfac4992c35474Mathias Agopian * 663301542828febc768e1df42892cfac4992c35474Mathias Agopian */ 673301542828febc768e1df42892cfac4992c35474Mathias Agopian 688ef3c89eb2030395f8a342bd16dbb344957ab275Aravind Akellaconst char* SensorService::WAKE_LOCK_NAME = "SensorService_wakelock"; 6953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiseruint8_t SensorService::sHmacGlobalKey[128] = {}; 7053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiserbool SensorService::sHmacGlobalKeyIsValid = false; 7153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 7253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#define SENSOR_SERVICE_DIR "/data/system/sensor_service" 7353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#define SENSOR_SERVICE_HMAC_KEY_FILE SENSOR_SERVICE_DIR "/hmac_key" 7498d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu#define SENSOR_SERVICE_SCHED_FIFO_PRIORITY 10 7553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 76a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella// Permissions. 77dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xustatic const String16 sDumpPermission("android.permission.DUMP"); 78dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xustatic const String16 sLocationHardwarePermission("android.permission.LOCATION_HARDWARE"); 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; 320dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu if (!PermissionCache::checkCallingPermission(sDumpPermission)) { 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 } 340e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 341a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella mCurrentOperatingMode = RESTRICTED; 342e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu // temporarily stop all sensor direct report 343e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu for (auto &i : mDirectConnections) { 344e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu sp<SensorDirectConnection> connection(i.promote()); 345e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu if (connection != nullptr) { 346e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu connection->stopAll(true /* backupRecord */); 347e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 348e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 349e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 3504949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella dev.disableAllSensors(); 3514949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella // Clear all pending flush connections for all active sensors. If one of the active 3524949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella // connections has called flush() and the underlying sensor has been disabled before a 3534949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella // flush complete event is returned, we need to remove the connection from this queue. 3544949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella for (size_t i=0 ; i< mActiveSensors.size(); ++i) { 3554949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella mActiveSensors.valueAt(i)->clearAllPendingFlushConnections(); 3564949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella } 357841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella mWhiteListedPackage.setTo(String8(args[1])); 358444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella return status_t(NO_ERROR); 359444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } else if (args.size() == 1 && args[0] == String16("enable")) { 360444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // If currently in restricted mode, reset back to NORMAL mode else ignore. 361444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (mCurrentOperatingMode == RESTRICTED) { 362444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella mCurrentOperatingMode = NORMAL; 363444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella dev.enableAllSensors(); 364e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu // recover all sensor direct report 365e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu for (auto &i : mDirectConnections) { 366e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu sp<SensorDirectConnection> connection(i.promote()); 367e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu if (connection != nullptr) { 368e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu connection->recoverAll(); 369e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 370e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 3716c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } 372841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (mCurrentOperatingMode == DATA_INJECTION) { 373841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella resetToNormalModeLocked(); 374841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } 375841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella mWhiteListedPackage.clear(); 376444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella return status_t(NO_ERROR); 377841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } else if (args.size() == 2 && args[0] == String16("data_injection")) { 378841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (mCurrentOperatingMode == NORMAL) { 379841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella dev.disableAllSensors(); 380841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella status_t err = dev.setMode(DATA_INJECTION); 381841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (err == NO_ERROR) { 382841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella mCurrentOperatingMode = DATA_INJECTION; 383841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } else { 384841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella // Re-enable sensors. 385841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella dev.enableAllSensors(); 386841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } 387841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella mWhiteListedPackage.setTo(String8(args[1])); 388841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella return NO_ERROR; 389841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } else if (mCurrentOperatingMode == DATA_INJECTION) { 390841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella // Already in DATA_INJECTION mode. Treat this as a no_op. 391841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella return NO_ERROR; 392841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } else { 393841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella // Transition to data injection mode supported only from NORMAL mode. 394841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella return INVALID_OPERATION; 395841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } 3960cc8f809924706c7d683da30605f432635dd5bb6Peng Xu } else if (!mSensors.hasAnySensor()) { 397ee155cadb23e84542cbf445c2aac89ae63df4cc7Aravind Akella result.append("No Sensors on the device\n"); 39853e5aa93fa2855616b9691c5e1878f1db1464aceAshutosh Joshi result.appendFormat("devInitCheck : %d\n", SensorDevice::getInstance().initCheck()); 399444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } else { 400444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // Default dump the sensor list and debugging information. 4010cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // 4026a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu result.append("Sensor Device:\n"); 4036a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu result.append(SensorDevice::getInstance().dump().c_str()); 4046a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 4056a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu result.append("Sensor List:\n"); 4060cc8f809924706c7d683da30605f432635dd5bb6Peng Xu result.append(mSensors.dump().c_str()); 4076c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 4086a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu result.append("Fusion States:\n"); 409444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella SensorFusion::getInstance().dump(result); 410444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella 4110cc8f809924706c7d683da30605f432635dd5bb6Peng Xu result.append("Recent Sensor events:\n"); 4126a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu for (auto&& i : mRecentEvent) { 4136a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu sp<SensorInterface> s = mSensors.getInterface(i.first); 414fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu if (!i.second->isEmpty()) { 415fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu if (privileged || s->getSensor().getRequiredPermission().isEmpty()) { 416fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu i.second->setFormat("normal"); 417fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu } else { 418fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu i.second->setFormat("mask_data"); 419fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu } 4206a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu // if there is events and sensor does not need special permission. 4216a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu result.appendFormat("%s: ", s->getSensor().getName().string()); 4226a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu result.append(i.second->dump().c_str()); 4236a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu } 4246a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu } 4250cc8f809924706c7d683da30605f432635dd5bb6Peng Xu 426444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.append("Active sensors:\n"); 427444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella for (size_t i=0 ; i<mActiveSensors.size() ; i++) { 428444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella int handle = mActiveSensors.keyAt(i); 429444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat("%s (handle=0x%08x, connections=%zu)\n", 430444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella getSensorName(handle).string(), 431444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella handle, 432444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella mActiveSensors.valueAt(i)->getNumConnections()); 433ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian } 4344c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella 435d4036b6b7f9609fe09efabdbfbb8c8f9428f76f7Andreas Gampe result.appendFormat("Socket Buffer size = %zd events\n", 436444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella mSocketBufferSize/sizeof(sensors_event_t)); 43718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella result.appendFormat("WakeLock Status: %s \n", mWakeLockAcquired ? "acquired" : 43818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella "not held"); 439444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat("Mode :"); 440444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella switch(mCurrentOperatingMode) { 441444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella case NORMAL: 442444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat(" NORMAL\n"); 443444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella break; 444444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella case RESTRICTED: 445841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella result.appendFormat(" RESTRICTED : %s\n", mWhiteListedPackage.string()); 446444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella break; 447444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella case DATA_INJECTION: 448841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella result.appendFormat(" DATA_INJECTION : %s\n", mWhiteListedPackage.string()); 449444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 4504c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella 451e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu result.appendFormat("%zd active connections\n", mActiveConnections.size()); 452444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella for (size_t i=0 ; i < mActiveConnections.size() ; i++) { 453444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella sp<SensorEventConnection> connection(mActiveConnections[i].promote()); 454444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (connection != 0) { 455444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat("Connection Number: %zu \n", i); 456444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella connection->dump(result); 457444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 4584c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 45918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella 460e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu result.appendFormat("%zd direct connections\n", mDirectConnections.size()); 461e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu for (size_t i = 0 ; i < mDirectConnections.size() ; i++) { 462e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu sp<SensorDirectConnection> connection(mDirectConnections[i].promote()); 463e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu if (connection != nullptr) { 464e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu result.appendFormat("Direct connection %zu:\n", i); 465e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu connection->dump(result); 466e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 467e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 468e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 46918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella result.appendFormat("Previous Registrations:\n"); 47018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella // Log in the reverse chronological order. 47118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella int currentIndex = (mNextSensorRegIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) % 47218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella SENSOR_REGISTRATIONS_BUF_SIZE; 47318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella const int startIndex = currentIndex; 47418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella do { 47518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella const SensorRegistrationInfo& reg_info = mLastNSensorRegistrations[currentIndex]; 47618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella if (SensorRegistrationInfo::isSentinel(reg_info)) { 47718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella // Ignore sentinel, proceed to next item. 47818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella currentIndex = (currentIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) % 47918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella SENSOR_REGISTRATIONS_BUF_SIZE; 48018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella continue; 48118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } 48251224681c9a80ff714d40c26d8f465fb1bae17e2Peng Xu result.appendFormat("%s\n", reg_info.dump().c_str()); 48318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella currentIndex = (currentIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) % 48418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella SENSOR_REGISTRATIONS_BUF_SIZE; 48518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } while(startIndex != currentIndex); 4864c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 487fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 488fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian write(fd, result.string(), result.size()); 489fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return NO_ERROR; 490fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 491fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 4920cc8f809924706c7d683da30605f432635dd5bb6Peng Xu//TODO: move to SensorEventConnection later 4939a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::cleanupAutoDisabledSensorLocked(const sp<SensorEventConnection>& connection, 4944342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh sensors_event_t const* buffer, const int count) { 4954342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh for (int i=0 ; i<count ; i++) { 4964342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh int handle = buffer[i].sensor; 4978493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (buffer[i].type == SENSOR_TYPE_META_DATA) { 4988493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella handle = buffer[i].meta_data.sensor; 4998493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } 5000e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella if (connection->hasSensor(handle)) { 501755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> si = getSensorInterfaceFromHandle(handle); 5020e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella // If this buffer has an event from a one_shot sensor and this connection is registered 5030e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella // for this particular one_shot sensor, try cleaning up the connection. 504755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (si != nullptr && 5050cc8f809924706c7d683da30605f432635dd5bb6Peng Xu si->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) { 5060cc8f809924706c7d683da30605f432635dd5bb6Peng Xu si->autoDisable(connection.get(), handle); 5079a844cf78f09953145200b4074d47589257a408cAravind Akella cleanupWithoutDisableLocked(connection, handle); 5084342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 509a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella 5104342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 511a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella } 5124342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh} 5134342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 51447e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xubool SensorService::threadLoop() { 515a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block ALOGD("nuSensorService thread starting..."); 516fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 517eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // each virtual sensor could generate an event per "real" event, that's why we need to size 518eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT. in practice, this is too 519eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // aggressive, but guaranteed to be enough. 5200cc8f809924706c7d683da30605f432635dd5bb6Peng Xu const size_t vcount = mSensors.getVirtualSensors().size(); 52190ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT; 5220cc8f809924706c7d683da30605f432635dd5bb6Peng Xu const size_t numEventMax = minBufferSize / (1 + vcount); 52390ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian 524f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian SensorDevice& device(SensorDevice::getInstance()); 525fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 5264342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh const int halVersion = device.getHalDeviceVersion(); 527fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian do { 5288493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella ssize_t count = device.poll(mSensorEventBuffer, numEventMax); 5298493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (count < 0) { 530f5a1230d322c14c42331d0a1536b50c87742973bSteve Block ALOGE("sensor poll failed (%s)", strerror(-count)); 531fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian break; 532fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 53356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 53456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // Reset sensors_event_t.flags to zero for all events in the buffer. 53556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella for (int i = 0; i < count; i++) { 5368493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mSensorEventBuffer[i].flags = 0; 53756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 538e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella 539eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // Make a copy of the connection vector as some connections may be removed during the course 540eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // of this loop (especially when one-shot sensor events are present in the sensor_event 541eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // buffer). Promote all connections to StrongPointers before the lock is acquired. If the 542eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // destructor of the sp gets called when the lock is acquired, it may result in a deadlock 543eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // as ~SensorEventConnection() needs to acquire mLock again for cleanup. So copy all the 544eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // strongPointers to a vector before the lock is acquired. 545e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella SortedVector< sp<SensorEventConnection> > activeConnections; 546b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella populateActiveConnections(&activeConnections); 547eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu 5489a844cf78f09953145200b4074d47589257a408cAravind Akella Mutex::Autolock _l(mLock); 5499a844cf78f09953145200b4074d47589257a408cAravind Akella // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The 5509a844cf78f09953145200b4074d47589257a408cAravind Akella // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock, 5519a844cf78f09953145200b4074d47589257a408cAravind Akella // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should 5529a844cf78f09953145200b4074d47589257a408cAravind Akella // not be interleaved with decrementing SensorEventConnection::mWakeLockRefCount and 5539a844cf78f09953145200b4074d47589257a408cAravind Akella // releasing the wakelock. 5549a844cf78f09953145200b4074d47589257a408cAravind Akella bool bufferHasWakeUpEvent = false; 5554342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh for (int i = 0; i < count; i++) { 5568493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (isWakeUpSensorEvent(mSensorEventBuffer[i])) { 5579a844cf78f09953145200b4074d47589257a408cAravind Akella bufferHasWakeUpEvent = true; 5589a844cf78f09953145200b4074d47589257a408cAravind Akella break; 5594342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 5604342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 5614342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 5629a844cf78f09953145200b4074d47589257a408cAravind Akella if (bufferHasWakeUpEvent && !mWakeLockAcquired) { 563b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella setWakeLockAcquiredLocked(true); 5649a844cf78f09953145200b4074d47589257a408cAravind Akella } 5658493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella recordLastValueLocked(mSensorEventBuffer, count); 56694e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian 567f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian // handle virtual sensors 568f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian if (count && vcount) { 5698493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella sensors_event_t const * const event = mSensorEventBuffer; 570755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (!mActiveVirtualSensors.empty()) { 571f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian size_t k = 0; 572984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian SensorFusion& fusion(SensorFusion::getInstance()); 573984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian if (fusion.isEnabled()) { 574984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t i=0 ; i<size_t(count) ; i++) { 575984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian fusion.process(event[i]); 576984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 577984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 578d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) { 579755c451c7861a029e26e5f16e319b629169e656dPeng Xu for (int handle : mActiveVirtualSensors) { 580d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian if (count + k >= minBufferSize) { 581d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian ALOGE("buffer too small to hold all events: " 582db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn "count=%zd, k=%zu, size=%zu", 583d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian count, k, minBufferSize); 584d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian break; 585d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian } 586f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sensors_event_t out; 587755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> si = mSensors.getInterface(handle); 588755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (si == nullptr) { 589755c451c7861a029e26e5f16e319b629169e656dPeng Xu ALOGE("handle %d is not an valid virtual sensor", handle); 590755c451c7861a029e26e5f16e319b629169e656dPeng Xu continue; 591755c451c7861a029e26e5f16e319b629169e656dPeng Xu } 592755c451c7861a029e26e5f16e319b629169e656dPeng Xu 593d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian if (si->process(&out, event[i])) { 5948493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mSensorEventBuffer[count + k] = out; 595f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian k++; 596f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 597f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 598f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 599f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian if (k) { 600f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian // record the last synthesized values 6018493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella recordLastValueLocked(&mSensorEventBuffer[count], k); 602f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian count += k; 603f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian // sort the buffer by time-stamps 6048493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella sortEventBuffer(mSensorEventBuffer, count); 605f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 606f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 607f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 608f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 6094342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // handle backward compatibility for RotationVector sensor 6104342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) { 6114342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh for (int i = 0; i < count; i++) { 6128493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (mSensorEventBuffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) { 6134342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // All the 4 components of the quaternion should be available 6144342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // No heading accuracy. Set it to -1 6158493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mSensorEventBuffer[i].data[4] = -1; 6168493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } 6178493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } 6188493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } 6198493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella 6208493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella for (int i = 0; i < count; ++i) { 6210cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // Map flush_complete_events in the buffer to SensorEventConnections which called flush 6220cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // on the hardware sensor. mapFlushEventsToConnections[i] will be the 6230cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // SensorEventConnection mapped to the corresponding flush_complete_event in 6240cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // mSensorEventBuffer[i] if such a mapping exists (NULL otherwise). 6258493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mMapFlushEventsToConnections[i] = NULL; 6268493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (mSensorEventBuffer[i].type == SENSOR_TYPE_META_DATA) { 6278493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella const int sensor_handle = mSensorEventBuffer[i].meta_data.sensor; 6288493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella SensorRecord* rec = mActiveSensors.valueFor(sensor_handle); 6298493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (rec != NULL) { 6308493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mMapFlushEventsToConnections[i] = rec->getFirstPendingFlushConnection(); 6318493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella rec->removeFirstPendingFlushConnection(); 6324342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 6334342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 6342576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 6352576cb63b3fe1592f54816625036566b9eb0793aPeng Xu // handle dynamic sensor meta events, process registration and unregistration of dynamic 6362576cb63b3fe1592f54816625036566b9eb0793aPeng Xu // sensor based on content of event. 6372576cb63b3fe1592f54816625036566b9eb0793aPeng Xu if (mSensorEventBuffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META) { 6382576cb63b3fe1592f54816625036566b9eb0793aPeng Xu if (mSensorEventBuffer[i].dynamic_sensor_meta.connected) { 6392576cb63b3fe1592f54816625036566b9eb0793aPeng Xu int handle = mSensorEventBuffer[i].dynamic_sensor_meta.handle; 6402576cb63b3fe1592f54816625036566b9eb0793aPeng Xu const sensor_t& dynamicSensor = 6412576cb63b3fe1592f54816625036566b9eb0793aPeng Xu *(mSensorEventBuffer[i].dynamic_sensor_meta.sensor); 6422576cb63b3fe1592f54816625036566b9eb0793aPeng Xu ALOGI("Dynamic sensor handle 0x%x connected, type %d, name %s", 6432576cb63b3fe1592f54816625036566b9eb0793aPeng Xu handle, dynamicSensor.type, dynamicSensor.name); 6442576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 6450cc8f809924706c7d683da30605f432635dd5bb6Peng Xu if (mSensors.isNewHandle(handle)) { 6466a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu const auto& uuid = mSensorEventBuffer[i].dynamic_sensor_meta.uuid; 64747e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu sensor_t s = dynamicSensor; 64847e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu // make sure the dynamic sensor flag is set 64947e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu s.flags |= DYNAMIC_SENSOR_MASK; 65047e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu // force the handle to be consistent 65147e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu s.handle = handle; 6526a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 6536a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu SensorInterface *si = new HardwareSensor(s, uuid); 65447e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu 6550cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // This will release hold on dynamic sensor meta, so it should be called 6560cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // after Sensor object is created. 65747e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu device.handleDynamicSensorConnection(handle, true /*connected*/); 6586a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu registerDynamicSensorLocked(si); 65947e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu } else { 66047e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu ALOGE("Handle %d has been used, cannot use again before reboot.", handle); 66147e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu } 6622576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } else { 6632576cb63b3fe1592f54816625036566b9eb0793aPeng Xu int handle = mSensorEventBuffer[i].dynamic_sensor_meta.handle; 6642576cb63b3fe1592f54816625036566b9eb0793aPeng Xu ALOGI("Dynamic sensor handle 0x%x disconnected", handle); 6652576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 6662576cb63b3fe1592f54816625036566b9eb0793aPeng Xu device.handleDynamicSensorConnection(handle, false /*connected*/); 6676a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu if (!unregisterDynamicSensorLocked(handle)) { 6682576cb63b3fe1592f54816625036566b9eb0793aPeng Xu ALOGE("Dynamic sensor release error."); 6692576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 6702576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 6712576cb63b3fe1592f54816625036566b9eb0793aPeng Xu size_t numConnections = activeConnections.size(); 6722576cb63b3fe1592f54816625036566b9eb0793aPeng Xu for (size_t i=0 ; i < numConnections; ++i) { 6732576cb63b3fe1592f54816625036566b9eb0793aPeng Xu if (activeConnections[i] != NULL) { 6742576cb63b3fe1592f54816625036566b9eb0793aPeng Xu activeConnections[i]->removeSensor(handle); 6752576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 6762576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 6772576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 6782576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 6794342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 6804342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 6812576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 6829a844cf78f09953145200b4074d47589257a408cAravind Akella // Send our events to clients. Check the state of wake lock for each client and release the 6839a844cf78f09953145200b4074d47589257a408cAravind Akella // lock if none of the clients need it. 6849a844cf78f09953145200b4074d47589257a408cAravind Akella bool needsWakeLock = false; 6858493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella size_t numConnections = activeConnections.size(); 6868493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella for (size_t i=0 ; i < numConnections; ++i) { 687e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella if (activeConnections[i] != 0) { 688e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch, 6898493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mMapFlushEventsToConnections); 690e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella needsWakeLock |= activeConnections[i]->needsWakeLock(); 6918493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella // If the connection has one-shot sensors, it may be cleaned up after first trigger. 6928493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella // Early check for one-shot sensors. 693e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella if (activeConnections[i]->hasOneShotSensors()) { 694e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer, 695e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella count); 6968493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } 697fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 698fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 6994342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 7009a844cf78f09953145200b4074d47589257a408cAravind Akella if (mWakeLockAcquired && !needsWakeLock) { 701b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella setWakeLockAcquiredLocked(false); 7029a844cf78f09953145200b4074d47589257a408cAravind Akella } 7038493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } while (!Thread::exitPending()); 704fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 7053c20fbed7f3a916ced10f2ed5a272271b7d81edeSteve Block ALOGW("Exiting SensorService::threadLoop => aborting..."); 7061a62301fc58cd2af18239b0415813461bf5fc41bMathias Agopian abort(); 707fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return false; 708fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 709fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 71056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellasp<Looper> SensorService::getLooper() const { 71156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella return mLooper; 71256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella} 71356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 714b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::resetAllWakeLockRefCounts() { 715b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella SortedVector< sp<SensorEventConnection> > activeConnections; 716b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella populateActiveConnections(&activeConnections); 717b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella { 718b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella Mutex::Autolock _l(mLock); 719b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella for (size_t i=0 ; i < activeConnections.size(); ++i) { 720b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (activeConnections[i] != 0) { 721b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella activeConnections[i]->resetWakeLockRefCount(); 722b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 723b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 724b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella setWakeLockAcquiredLocked(false); 725b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 726b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella} 727b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella 728b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::setWakeLockAcquiredLocked(bool acquire) { 729b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (acquire) { 730b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (!mWakeLockAcquired) { 731b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME); 732b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mWakeLockAcquired = true; 733b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 734b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mLooper->wake(); 735b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } else { 736b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (mWakeLockAcquired) { 737b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella release_wake_lock(WAKE_LOCK_NAME); 738b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mWakeLockAcquired = false; 739b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 740b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 741b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella} 742b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella 743b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellabool SensorService::isWakeLockAcquired() { 744b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella Mutex::Autolock _l(mLock); 745b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella return mWakeLockAcquired; 746b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella} 747b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella 74856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellabool SensorService::SensorEventAckReceiver::threadLoop() { 74956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella ALOGD("new thread SensorEventAckReceiver"); 750b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella sp<Looper> looper = mService->getLooper(); 75156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella do { 752b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella bool wakeLockAcquired = mService->isWakeLockAcquired(); 753b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella int timeout = -1; 754b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (wakeLockAcquired) timeout = 5000; 755b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella int ret = looper->pollOnce(timeout); 756b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (ret == ALOOPER_POLL_TIMEOUT) { 757b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mService->resetAllWakeLockRefCounts(); 758b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 75956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } while(!Thread::exitPending()); 76056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella return false; 76156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella} 76256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 7639a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::recordLastValueLocked( 7644b84704b97300eff3ebfab85652e64d54149d205Aravind Akella const sensors_event_t* buffer, size_t count) { 7654b84704b97300eff3ebfab85652e64d54149d205Aravind Akella for (size_t i = 0; i < count; i++) { 7662576cb63b3fe1592f54816625036566b9eb0793aPeng Xu if (buffer[i].type == SENSOR_TYPE_META_DATA || 7672576cb63b3fe1592f54816625036566b9eb0793aPeng Xu buffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META || 7686a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO) { 7692576cb63b3fe1592f54816625036566b9eb0793aPeng Xu continue; 7702576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 7712576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 7726a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu auto logger = mRecentEvent.find(buffer[i].sensor); 7736a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu if (logger != mRecentEvent.end()) { 7746a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu logger->second->addEvent(buffer[i]); 77594e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian } 77694e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian } 77794e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian} 77894e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian 77947e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xuvoid SensorService::sortEventBuffer(sensors_event_t* buffer, size_t count) { 780f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian struct compar { 781f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian static int cmp(void const* lhs, void const* rhs) { 782f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sensors_event_t const* l = static_cast<sensors_event_t const*>(lhs); 783f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sensors_event_t const* r = static_cast<sensors_event_t const*>(rhs); 784a5c106a4f0afcf061728a1cb7c8c3b908728575dMathias Agopian return l->timestamp - r->timestamp; 785f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 786f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian }; 787f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian qsort(buffer, count, sizeof(sensors_event_t), compar::cmp); 788f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian} 789f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 7905d2707214dfb97bd8dfcc6620be36841d3c82420Mathias AgopianString8 SensorService::getSensorName(int handle) const { 7910cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return mSensors.getName(handle); 7925d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian} 7935d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian 794b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akellabool SensorService::isVirtualSensor(int handle) const { 795755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 796755c451c7861a029e26e5f16e319b629169e656dPeng Xu return sensor != nullptr && sensor->isVirtual(); 797b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella} 798b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella 7999a844cf78f09953145200b4074d47589257a408cAravind Akellabool SensorService::isWakeUpSensorEvent(const sensors_event_t& event) const { 8007869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan int handle = event.sensor; 8017869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan if (event.type == SENSOR_TYPE_META_DATA) { 8027869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan handle = event.meta_data.sensor; 8037869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan } 804755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 805755c451c7861a029e26e5f16e319b629169e656dPeng Xu return sensor != nullptr && sensor->getSensor().isWakeUpSensor(); 8069a844cf78f09953145200b4074d47589257a408cAravind Akella} 8079a844cf78f09953145200b4074d47589257a408cAravind Akella 80853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiserint32_t SensorService::getIdFromUuid(const Sensor::uuid_t &uuid) const { 80953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if ((uuid.i64[0] == 0) && (uuid.i64[1] == 0)) { 81053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // UUID is not supported for this device. 81153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return 0; 81253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 81353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if ((uuid.i64[0] == INT64_C(~0)) && (uuid.i64[1] == INT64_C(~0))) { 81453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // This sensor can be uniquely identified in the system by 81553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // the combination of its type and name. 81653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return -1; 81753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 81853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 81953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // We have a dynamic sensor. 82053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 82153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (!sHmacGlobalKeyIsValid) { 82253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Rather than risk exposing UUIDs, we cripple dynamic sensors. 82353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser ALOGW("HMAC key failure; dynamic sensor getId() will be wrong."); 82453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return 0; 82553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 82653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 82753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // We want each app author/publisher to get a different ID, so that the 82853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // same dynamic sensor cannot be tracked across apps by multiple 82953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // authors/publishers. So we use both our UUID and our User ID. 83053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Note potential confusion: 83153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // UUID => Universally Unique Identifier. 83253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // UID => User Identifier. 83353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // We refrain from using "uid" except as needed by API to try to 83453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // keep this distinction clear. 83553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 83653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser auto appUserId = IPCThreadState::self()->getCallingUid(); 83753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser uint8_t uuidAndApp[sizeof(uuid) + sizeof(appUserId)]; 83853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser memcpy(uuidAndApp, &uuid, sizeof(uuid)); 83953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser memcpy(uuidAndApp + sizeof(uuid), &appUserId, sizeof(appUserId)); 84053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 84153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Now we use our key on our UUID/app combo to get the hash. 84253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser uint8_t hash[EVP_MAX_MD_SIZE]; 84353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser unsigned int hashLen; 84453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (HMAC(EVP_sha256(), 84553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser sHmacGlobalKey, sizeof(sHmacGlobalKey), 84653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser uuidAndApp, sizeof(uuidAndApp), 84753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser hash, &hashLen) == nullptr) { 84853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Rather than risk exposing UUIDs, we cripple dynamic sensors. 84953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser ALOGW("HMAC failure; dynamic sensor getId() will be wrong."); 85053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return 0; 85153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 85253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 85353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser int32_t id = 0; 85453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (hashLen < sizeof(id)) { 85553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // We never expect this case, but out of paranoia, we handle it. 85653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Our 'id' length is already quite small, we don't want the 85753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // effective length of it to be even smaller. 85853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Rather than risk exposing UUIDs, we cripple dynamic sensors. 85953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser ALOGW("HMAC insufficient; dynamic sensor getId() will be wrong."); 86053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return 0; 86153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 86253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 86353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // This is almost certainly less than all of 'hash', but it's as secure 86453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // as we can be with our current 'id' length. 86553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser memcpy(&id, hash, sizeof(id)); 86653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 86753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Note at the beginning of the function that we return the values of 86853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // 0 and -1 to represent special cases. As a result, we can't return 86953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // those as dynamic sensor IDs. If we happened to hash to one of those 87053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // values, we change 'id' so we report as a dynamic sensor, and not as 87153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // one of those special cases. 87253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (id == -1) { 87353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser id = -2; 87453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } else if (id == 0) { 87553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser id = 1; 87653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 87753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return id; 87853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser} 87953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 88053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiservoid SensorService::makeUuidsIntoIdsForSensorList(Vector<Sensor> &sensorList) const { 88153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser for (auto &sensor : sensorList) { 88253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser int32_t id = getIdFromUuid(sensor.getUuid()); 88353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser sensor.setId(id); 88453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 88553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser} 88653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 8872c588c536090ea3e7e80db0e5031935b6026814cNick VaccaroVector<Sensor> SensorService::getSensorList(const String16& /* opPackageName */) { 88833264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian char value[PROPERTY_VALUE_MAX]; 88933264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian property_get("debug.sensors", value, "0"); 890700180487ffec09d9df1657b018a7caadac24b75Aravind Akella const Vector<Sensor>& initialSensorList = (atoi(value)) ? 8910cc8f809924706c7d683da30605f432635dd5bb6Peng Xu mSensors.getUserDebugSensors() : mSensors.getUserSensors(); 892700180487ffec09d9df1657b018a7caadac24b75Aravind Akella Vector<Sensor> accessibleSensorList; 893700180487ffec09d9df1657b018a7caadac24b75Aravind Akella for (size_t i = 0; i < initialSensorList.size(); i++) { 894700180487ffec09d9df1657b018a7caadac24b75Aravind Akella Sensor sensor = initialSensorList[i]; 8952c588c536090ea3e7e80db0e5031935b6026814cNick Vaccaro accessibleSensorList.add(sensor); 89633264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian } 89753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser makeUuidsIntoIdsForSensorList(accessibleSensorList); 898700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return accessibleSensorList; 899fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 900fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 90147e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng XuVector<Sensor> SensorService::getDynamicSensorList(const String16& opPackageName) { 9022576cb63b3fe1592f54816625036566b9eb0793aPeng Xu Vector<Sensor> accessibleSensorList; 9030cc8f809924706c7d683da30605f432635dd5bb6Peng Xu mSensors.forEachSensor( 9040cc8f809924706c7d683da30605f432635dd5bb6Peng Xu [&opPackageName, &accessibleSensorList] (const Sensor& sensor) -> bool { 905755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (sensor.isDynamicSensor()) { 906755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (canAccessSensor(sensor, "getDynamicSensorList", opPackageName)) { 907755c451c7861a029e26e5f16e319b629169e656dPeng Xu accessibleSensorList.add(sensor); 908755c451c7861a029e26e5f16e319b629169e656dPeng Xu } else { 909755c451c7861a029e26e5f16e319b629169e656dPeng Xu ALOGI("Skipped sensor %s because it requires permission %s and app op %" PRId32, 910755c451c7861a029e26e5f16e319b629169e656dPeng Xu sensor.getName().string(), 911755c451c7861a029e26e5f16e319b629169e656dPeng Xu sensor.getRequiredPermission().string(), 912755c451c7861a029e26e5f16e319b629169e656dPeng Xu sensor.getRequiredAppOp()); 913755c451c7861a029e26e5f16e319b629169e656dPeng Xu } 9140cc8f809924706c7d683da30605f432635dd5bb6Peng Xu } 9150cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return true; 9160cc8f809924706c7d683da30605f432635dd5bb6Peng Xu }); 91753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser makeUuidsIntoIdsForSensorList(accessibleSensorList); 9182576cb63b3fe1592f54816625036566b9eb0793aPeng Xu return accessibleSensorList; 9192576cb63b3fe1592f54816625036566b9eb0793aPeng Xu} 9202576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 921a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellasp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName, 922b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav int requestedMode, const String16& opPackageName) { 923a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella // Only 2 modes supported for a SensorEventConnection ... NORMAL and DATA_INJECTION. 924a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella if (requestedMode != NORMAL && requestedMode != DATA_INJECTION) { 925a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella return NULL; 926a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella } 927a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella 928a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella Mutex::Autolock _l(mLock); 929841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella // To create a client in DATA_INJECTION mode to inject data, SensorService should already be 930841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella // operating in DI mode. 931841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (requestedMode == DATA_INJECTION) { 932841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (mCurrentOperatingMode != DATA_INJECTION) return NULL; 933841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (!isWhiteListedPackage(packageName)) return NULL; 934841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } 935841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella 9365307d17fe33fc26eeeacd6339a9fbfe96cf56873Mathias Agopian uid_t uid = IPCThreadState::self()->getCallingUid(); 93758d450af6d956538e938661bbe7aef9f32e50badPeng Xu pid_t pid = IPCThreadState::self()->getCallingPid(); 93858d450af6d956538e938661bbe7aef9f32e50badPeng Xu 93958d450af6d956538e938661bbe7aef9f32e50badPeng Xu String8 connPackageName = 94058d450af6d956538e938661bbe7aef9f32e50badPeng Xu (packageName == "") ? String8::format("unknown_package_pid_%d", pid) : packageName; 94158d450af6d956538e938661bbe7aef9f32e50badPeng Xu String16 connOpPackageName = 94258d450af6d956538e938661bbe7aef9f32e50badPeng Xu (opPackageName == String16("")) ? String16(connPackageName) : opPackageName; 94358d450af6d956538e938661bbe7aef9f32e50badPeng Xu sp<SensorEventConnection> result(new SensorEventConnection(this, uid, connPackageName, 94458d450af6d956538e938661bbe7aef9f32e50badPeng Xu requestedMode == DATA_INJECTION, connOpPackageName)); 945a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella if (requestedMode == DATA_INJECTION) { 946a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella if (mActiveConnections.indexOf(result) < 0) { 947a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella mActiveConnections.add(result); 948a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella } 949a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella // Add the associated file descriptor to the Looper for polling whenever there is data to 950a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella // be injected. 951a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella result->updateLooperRegistration(mLooper); 952a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella } 953fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return result; 954fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 955fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 956841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akellaint SensorService::isDataInjectionEnabled() { 957a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella Mutex::Autolock _l(mLock); 958841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella return (mCurrentOperatingMode == DATA_INJECTION); 959a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella} 960a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella 961e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xusp<ISensorEventConnection> SensorService::createSensorDirectConnection( 962e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu const String16& opPackageName, uint32_t size, int32_t type, int32_t format, 963e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu const native_handle *resource) { 964e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu Mutex::Autolock _l(mLock); 965e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 966e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu struct sensors_direct_mem_t mem = { 967e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu .type = type, 968e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu .format = format, 969e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu .size = size, 970e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu .handle = resource, 971e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu }; 972e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu uid_t uid = IPCThreadState::self()->getCallingUid(); 973e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 974e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu if (mem.handle == nullptr) { 975e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu ALOGE("Failed to clone resource handle"); 976e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu return nullptr; 977e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 978e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 979e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu // check format 980e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu if (format != SENSOR_DIRECT_FMT_SENSORS_EVENT) { 981e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu ALOGE("Direct channel format %d is unsupported!", format); 982e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu return nullptr; 983e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 984e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 985e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu // check for duplication 986e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu for (auto &i : mDirectConnections) { 987e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu sp<SensorDirectConnection> connection(i.promote()); 988e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu if (connection != nullptr && connection->isEquivalent(&mem)) { 989f88e2b95b2cd6238f6758ef6a180fbd277f06ff2Peng Xu ALOGE("Duplicate create channel request for the same share memory"); 990e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu return nullptr; 991e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 992e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 993e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 994e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu // check specific to memory type 995e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu switch(type) { 996e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu case SENSOR_DIRECT_MEM_TYPE_ASHMEM: { // channel backed by ashmem 9978b1517ced6a294f479e261961d03c7356dec0838Brian Duddie if (resource->numFds < 1) { 9988b1517ced6a294f479e261961d03c7356dec0838Brian Duddie ALOGE("Ashmem direct channel requires a memory region to be supplied"); 9998b1517ced6a294f479e261961d03c7356dec0838Brian Duddie android_errorWriteLog(0x534e4554, "70986337"); // SafetyNet 10008b1517ced6a294f479e261961d03c7356dec0838Brian Duddie return nullptr; 10018b1517ced6a294f479e261961d03c7356dec0838Brian Duddie } 1002e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu int fd = resource->data[0]; 1003e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu int size2 = ashmem_get_size_region(fd); 1004e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu // check size consistency 10058b1517ced6a294f479e261961d03c7356dec0838Brian Duddie if (size2 < static_cast<int64_t>(size)) { 1006f88e2b95b2cd6238f6758ef6a180fbd277f06ff2Peng Xu ALOGE("Ashmem direct channel size %" PRIu32 " greater than shared memory size %d", 1007f88e2b95b2cd6238f6758ef6a180fbd277f06ff2Peng Xu size, size2); 1008e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu return nullptr; 1009e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 1010e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu break; 1011e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 1012e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu case SENSOR_DIRECT_MEM_TYPE_GRALLOC: 1013f88e2b95b2cd6238f6758ef6a180fbd277f06ff2Peng Xu // no specific checks for gralloc 1014e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu break; 1015e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu default: 1016e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu ALOGE("Unknown direct connection memory type %d", type); 1017e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu return nullptr; 1018e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 1019e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 1020e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu native_handle_t *clone = native_handle_clone(resource); 1021e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu if (!clone) { 1022e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu return nullptr; 1023e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 1024e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 1025e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu SensorDirectConnection* conn = nullptr; 1026e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu SensorDevice& dev(SensorDevice::getInstance()); 1027e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu int channelHandle = dev.registerDirectChannel(&mem); 1028e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 1029e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu if (channelHandle <= 0) { 1030e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu ALOGE("SensorDevice::registerDirectChannel returns %d", channelHandle); 1031e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } else { 1032e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu mem.handle = clone; 1033e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu conn = new SensorDirectConnection(this, uid, &mem, channelHandle, opPackageName); 1034e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 1035e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 1036e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu if (conn == nullptr) { 1037e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu native_handle_close(clone); 1038e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu native_handle_delete(clone); 1039e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } else { 1040e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu // add to list of direct connections 1041e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu // sensor service should never hold pointer or sp of SensorDirectConnection object. 1042e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu mDirectConnections.add(wp<SensorDirectConnection>(conn)); 1043e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 1044e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu return conn; 1045e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu} 1046e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 1047dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xuint SensorService::setOperationParameter( 104888711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov int32_t handle, int32_t type, 104988711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov const Vector<float> &floats, const Vector<int32_t> &ints) { 1050dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu Mutex::Autolock _l(mLock); 1051dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu 105288711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov if (!checkCallingPermission(sLocationHardwarePermission, nullptr, nullptr)) { 1053dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu return PERMISSION_DENIED; 1054dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu } 1055dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu 1056dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu bool isFloat = true; 105788711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov bool isCustom = false; 1058dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu size_t expectSize = INT32_MAX; 1059dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu switch (type) { 1060dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu case AINFO_LOCAL_GEOMAGNETIC_FIELD: 1061dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu isFloat = true; 1062dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu expectSize = 3; 1063dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu break; 1064dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu case AINFO_LOCAL_GRAVITY: 1065dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu isFloat = true; 1066dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu expectSize = 1; 1067dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu break; 1068dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu case AINFO_DOCK_STATE: 1069dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu case AINFO_HIGH_PERFORMANCE_MODE: 1070dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu case AINFO_MAGNETIC_FIELD_CALIBRATION: 1071dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu isFloat = false; 1072dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu expectSize = 1; 1073dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu break; 1074dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu default: 107588711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov // CUSTOM events must only contain float data; it may have variable size 107688711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov if (type < AINFO_CUSTOM_START || type >= AINFO_DEBUGGING_START || 107788711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov ints.size() || 107888711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov sizeof(additional_info_event_t::data_float)/sizeof(float) < floats.size() || 107988711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov handle < 0) { 108088711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov return BAD_VALUE; 108188711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov } 108288711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov isFloat = true; 108388711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov isCustom = true; 108488711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov expectSize = floats.size(); 108588711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov break; 108688711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov } 108788711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov 108888711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov if (!isCustom && handle != -1) { 108988711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov return BAD_VALUE; 1090dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu } 1091dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu 1092dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu // three events: first one is begin tag, last one is end tag, the one in the middle 1093dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu // is the payload. 1094dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu sensors_event_t event[3]; 1095dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu int64_t timestamp = elapsedRealtimeNano(); 1096dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu for (sensors_event_t* i = event; i < event + 3; i++) { 1097dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu *i = (sensors_event_t) { 1098dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu .version = sizeof(sensors_event_t), 109988711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov .sensor = handle, 1100dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu .type = SENSOR_TYPE_ADDITIONAL_INFO, 1101dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu .timestamp = timestamp++, 1102dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu .additional_info = (additional_info_event_t) { 1103dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu .serial = 0 1104dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu } 1105dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu }; 1106dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu } 1107dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu 1108dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu event[0].additional_info.type = AINFO_BEGIN; 1109dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu event[1].additional_info.type = type; 1110dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu event[2].additional_info.type = AINFO_END; 1111dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu 1112dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu if (isFloat) { 1113dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu if (floats.size() != expectSize) { 1114dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu return BAD_VALUE; 1115dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu } 1116dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu for (size_t i = 0; i < expectSize; ++i) { 1117dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu event[1].additional_info.data_float[i] = floats[i]; 1118dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu } 1119dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu } else { 1120dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu if (ints.size() != expectSize) { 1121dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu return BAD_VALUE; 1122dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu } 1123dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu for (size_t i = 0; i < expectSize; ++i) { 1124dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu event[1].additional_info.data_int32[i] = ints[i]; 1125dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu } 1126dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu } 1127dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu 1128dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu SensorDevice& dev(SensorDevice::getInstance()); 1129dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu for (sensors_event_t* i = event; i < event + 3; i++) { 1130dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu int ret = dev.injectSensorData(i); 1131dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu if (ret != NO_ERROR) { 1132dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu return ret; 1133dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu } 1134dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu } 1135dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu return NO_ERROR; 1136dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu} 1137dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu 1138a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatus_t SensorService::resetToNormalMode() { 1139a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella Mutex::Autolock _l(mLock); 1140a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella return resetToNormalModeLocked(); 1141a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella} 1142a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella 1143a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatus_t SensorService::resetToNormalModeLocked() { 1144a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella SensorDevice& dev(SensorDevice::getInstance()); 1145a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella status_t err = dev.setMode(NORMAL); 1146bfac17eed90d410de51413ef2484f79fb0e241e2Aniroop Mathur if (err == NO_ERROR) { 1147bfac17eed90d410de51413ef2484f79fb0e241e2Aniroop Mathur mCurrentOperatingMode = NORMAL; 1148bfac17eed90d410de51413ef2484f79fb0e241e2Aniroop Mathur dev.enableAllSensors(); 1149bfac17eed90d410de51413ef2484f79fb0e241e2Aniroop Mathur } 1150a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella return err; 1151a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella} 1152a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella 115347e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xuvoid SensorService::cleanupConnection(SensorEventConnection* c) { 1154fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian Mutex::Autolock _l(mLock); 1155db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian const wp<SensorEventConnection> connection(c); 11567c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian size_t size = mActiveSensors.size(); 1157db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn ALOGD_IF(DEBUG_CONNECTIONS, "%zu active sensors", size); 11587c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian for (size_t i=0 ; i<size ; ) { 1159db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian int handle = mActiveSensors.keyAt(i); 1160db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian if (c->hasSensor(handle)) { 1161db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn ALOGD_IF(DEBUG_CONNECTIONS, "%zu: disabling handle=0x%08x", i, handle); 1162755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 1163755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (sensor != nullptr) { 1164db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian sensor->activate(c, false); 1165755c451c7861a029e26e5f16e319b629169e656dPeng Xu } else { 1166755c451c7861a029e26e5f16e319b629169e656dPeng Xu ALOGE("sensor interface of handle=0x%08x is null!", handle); 1167f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 11688a96955c8e14db40b16164236830fc9506a00872Aravind Akella c->removeSensor(handle); 1169db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian } 1170db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian SensorRecord* rec = mActiveSensors.valueAt(i); 1171db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn ALOGE_IF(!rec, "mActiveSensors[%zu] is null (handle=0x%08x)!", i, handle); 1172a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block ALOGD_IF(DEBUG_CONNECTIONS, 1173db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn "removing connection %p for sensor[%zu].handle=0x%08x", 1174a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian c, i, handle); 1175a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian 1176db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian if (rec && rec->removeConnection(connection)) { 1177a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block ALOGD_IF(DEBUG_CONNECTIONS, "... and it was the last connection"); 11787c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian mActiveSensors.removeItemsAt(i, 1); 1179755c451c7861a029e26e5f16e319b629169e656dPeng Xu mActiveVirtualSensors.erase(handle); 11807c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian delete rec; 11817c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian size--; 11827c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian } else { 11837c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian i++; 1184fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 1185fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 11868a96955c8e14db40b16164236830fc9506a00872Aravind Akella c->updateLooperRegistration(mLooper); 11877c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian mActiveConnections.remove(connection); 1188787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian BatteryService::cleanup(c->getUid()); 11899a844cf78f09953145200b4074d47589257a408cAravind Akella if (c->needsWakeLock()) { 11909a844cf78f09953145200b4074d47589257a408cAravind Akella checkWakeLockStateLocked(); 11919a844cf78f09953145200b4074d47589257a408cAravind Akella } 11924f707f8b3da68d3055db895da9ae5216cc4f483aPeng Xu 11934f707f8b3da68d3055db895da9ae5216cc4f483aPeng Xu SensorDevice& dev(SensorDevice::getInstance()); 11944f707f8b3da68d3055db895da9ae5216cc4f483aPeng Xu dev.notifyConnectionDestroyed(c); 1195fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 1196fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 1197e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xuvoid SensorService::cleanupConnection(SensorDirectConnection* c) { 1198e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu Mutex::Autolock _l(mLock); 1199e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 1200e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu SensorDevice& dev(SensorDevice::getInstance()); 1201e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu dev.unregisterDirectChannel(c->getHalChannelHandle()); 1202e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu mDirectConnections.remove(c); 1203e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu} 1204e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 1205755c451c7861a029e26e5f16e319b629169e656dPeng Xusp<SensorInterface> SensorService::getSensorInterfaceFromHandle(int handle) const { 12060cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return mSensors.getInterface(handle); 120747e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu} 120847e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu 1209fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::enable(const sp<SensorEventConnection>& connection, 1210b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags, 121147e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu const String16& opPackageName) { 121250df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian if (mInitCheck != NO_ERROR) 121350df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian return mInitCheck; 121450df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian 1215755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 1216755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (sensor == nullptr || 1217755c451c7861a029e26e5f16e319b629169e656dPeng Xu !canAccessSensor(sensor->getSensor(), "Tried enabling", opPackageName)) { 1218700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return BAD_VALUE; 1219700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } 1220700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 1221ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian Mutex::Autolock _l(mLock); 1222e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu if (mCurrentOperatingMode != NORMAL 1223841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella && !isWhiteListedPackage(connection->getPackageName())) { 12244949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella return INVALID_OPERATION; 12254949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella } 12264949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella 12274342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh SensorRecord* rec = mActiveSensors.valueFor(handle); 12284342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (rec == 0) { 12294342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh rec = new SensorRecord(connection); 12304342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh mActiveSensors.add(handle, rec); 12314342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (sensor->isVirtual()) { 1232755c451c7861a029e26e5f16e319b629169e656dPeng Xu mActiveVirtualSensors.emplace(handle); 12333560fb24b668675627934356f210d84d19bf4e56Mathias Agopian } 12344342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } else { 12354342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (rec->addConnection(connection)) { 12369a844cf78f09953145200b4074d47589257a408cAravind Akella // this sensor is already activated, but we are adding a connection that uses it. 12379a844cf78f09953145200b4074d47589257a408cAravind Akella // Immediately send down the last known value of the requested sensor if it's not a 12384342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // "continuous" sensor. 12390e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ON_CHANGE) { 12409a844cf78f09953145200b4074d47589257a408cAravind Akella // NOTE: The wake_up flag of this event may get set to 12419a844cf78f09953145200b4074d47589257a408cAravind Akella // WAKE_UP_SENSOR_EVENT_NEEDS_ACK if this is a wake_up event. 12426a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 12436a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu auto logger = mRecentEvent.find(handle); 12446a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu if (logger != mRecentEvent.end()) { 1245444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella sensors_event_t event; 1246444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // It is unlikely that this buffer is empty as the sensor is already active. 1247444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // One possible corner case may be two applications activating an on-change 1248444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // sensor at the same time. 12496a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu if(logger->second->populateLastEvent(&event)) { 1250444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella event.sensor = handle; 1251444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (event.version == sizeof(sensors_event_t)) { 1252444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (isWakeUpSensorEvent(event) && !mWakeLockAcquired) { 1253444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella setWakeLockAcquiredLocked(true); 1254444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 1255444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella connection->sendEvents(&event, 1, NULL); 1256444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (!connection->needsWakeLock() && mWakeLockAcquired) { 1257444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella checkWakeLockStateLocked(); 1258444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 1259444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 12609a844cf78f09953145200b4074d47589257a408cAravind Akella } 1261f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 12627c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian } 1263fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 1264fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 12654342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 12664342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (connection->addSensor(handle)) { 12674342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh BatteryService::enableSensor(connection->getUid(), handle); 12684342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // the sensor was added (which means it wasn't already there) 12694342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // so, see if this connection becomes active 12704342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (mActiveConnections.indexOf(connection) < 0) { 12714342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh mActiveConnections.add(connection); 12724342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 12734342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } else { 12744342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh ALOGW("sensor %08x already enabled in connection %p (ignoring)", 12754342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh handle, connection.get()); 12764342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 12774342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 1278d8a5ce39101f569f6bdab696ed02623e5aff7451Aniroop Mathur // Check maximum delay for the sensor. 1279663720b29f412756b8599897df9f8e32eb930be2Jim Kaye nsecs_t maxDelayNs = sensor->getSensor().getMaxDelay() * 1000LL; 1280d8a5ce39101f569f6bdab696ed02623e5aff7451Aniroop Mathur if (maxDelayNs > 0 && (samplingPeriodNs > maxDelayNs)) { 1281d8a5ce39101f569f6bdab696ed02623e5aff7451Aniroop Mathur samplingPeriodNs = maxDelayNs; 1282d8a5ce39101f569f6bdab696ed02623e5aff7451Aniroop Mathur } 1283d8a5ce39101f569f6bdab696ed02623e5aff7451Aniroop Mathur 1284724d91d778e71c8186399f4955de14b54812b3edAravind Akella nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs(); 1285724d91d778e71c8186399f4955de14b54812b3edAravind Akella if (samplingPeriodNs < minDelayNs) { 1286724d91d778e71c8186399f4955de14b54812b3edAravind Akella samplingPeriodNs = minDelayNs; 1287724d91d778e71c8186399f4955de14b54812b3edAravind Akella } 1288724d91d778e71c8186399f4955de14b54812b3edAravind Akella 12896c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d" 12906c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella "rate=%" PRId64 " timeout== %" PRId64"", 1291724d91d778e71c8186399f4955de14b54812b3edAravind Akella handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs); 1292724d91d778e71c8186399f4955de14b54812b3edAravind Akella 12934949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella status_t err = sensor->batch(connection.get(), handle, 0, samplingPeriodNs, 1294724d91d778e71c8186399f4955de14b54812b3edAravind Akella maxBatchReportLatencyNs); 12956c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 129620483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // Call flush() before calling activate() on the sensor. Wait for a first 129720483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // flush complete event before sending events on this connection. Ignore 129820483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // one-shot sensors which don't support flush(). Ignore on-change sensors 129920483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // to maintain the on-change logic (any on-change events except the initial 130020483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // one should be trigger by a change in value). Also if this sensor isn't 130120483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // already active, don't call flush(). 130220483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu if (err == NO_ERROR && 13032576cb63b3fe1592f54816625036566b9eb0793aPeng Xu sensor->getSensor().getReportingMode() == AREPORTING_MODE_CONTINUOUS && 13045466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella rec->getNumConnections() > 1) { 13055466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella connection->setFirstFlushPending(handle, true); 13064c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella status_t err_flush = sensor->flush(connection.get(), handle); 13075466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // Flush may return error if the underlying h/w sensor uses an older HAL. 13086c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella if (err_flush == NO_ERROR) { 13096c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella rec->addPendingFlushConnection(connection.get()); 13105466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella } else { 13115466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella connection->setFirstFlushPending(handle, false); 13124c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 13134c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 1314724d91d778e71c8186399f4955de14b54812b3edAravind Akella 1315724d91d778e71c8186399f4955de14b54812b3edAravind Akella if (err == NO_ERROR) { 1316724d91d778e71c8186399f4955de14b54812b3edAravind Akella ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle); 1317724d91d778e71c8186399f4955de14b54812b3edAravind Akella err = sensor->activate(connection.get(), true); 1318724d91d778e71c8186399f4955de14b54812b3edAravind Akella } 1319724d91d778e71c8186399f4955de14b54812b3edAravind Akella 13208a96955c8e14db40b16164236830fc9506a00872Aravind Akella if (err == NO_ERROR) { 13218a96955c8e14db40b16164236830fc9506a00872Aravind Akella connection->updateLooperRegistration(mLooper); 132251224681c9a80ff714d40c26d8f465fb1bae17e2Peng Xu 132351224681c9a80ff714d40c26d8f465fb1bae17e2Peng Xu mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex) = 132451224681c9a80ff714d40c26d8f465fb1bae17e2Peng Xu SensorRegistrationInfo(handle, connection->getPackageName(), 132551224681c9a80ff714d40c26d8f465fb1bae17e2Peng Xu samplingPeriodNs, maxBatchReportLatencyNs, true); 132618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mNextSensorRegIndex = (mNextSensorRegIndex + 1) % SENSOR_REGISTRATIONS_BUF_SIZE; 132756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 132856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 13294342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (err != NO_ERROR) { 1330724d91d778e71c8186399f4955de14b54812b3edAravind Akella // batch/activate has failed, reset our state. 1331ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian cleanupWithoutDisableLocked(connection, handle); 13324342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 1333fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return err; 1334fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 1335fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 133647e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xustatus_t SensorService::disable(const sp<SensorEventConnection>& connection, int handle) { 133750df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian if (mInitCheck != NO_ERROR) 133850df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian return mInitCheck; 133950df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian 1340ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian Mutex::Autolock _l(mLock); 1341ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian status_t err = cleanupWithoutDisableLocked(connection, handle); 13424342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (err == NO_ERROR) { 1343755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 1344755c451c7861a029e26e5f16e319b629169e656dPeng Xu err = sensor != nullptr ? sensor->activate(connection.get(), false) : status_t(BAD_VALUE); 134518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella 134618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } 134718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella if (err == NO_ERROR) { 134851224681c9a80ff714d40c26d8f465fb1bae17e2Peng Xu mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex) = 134951224681c9a80ff714d40c26d8f465fb1bae17e2Peng Xu SensorRegistrationInfo(handle, connection->getPackageName(), 0, 0, false); 135018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mNextSensorRegIndex = (mNextSensorRegIndex + 1) % SENSOR_REGISTRATIONS_BUF_SIZE; 13514342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 13524342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh return err; 13534342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh} 13544342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 1355ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisable( 1356ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian const sp<SensorEventConnection>& connection, int handle) { 1357fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian Mutex::Autolock _l(mLock); 1358ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian return cleanupWithoutDisableLocked(connection, handle); 1359ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian} 1360ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian 1361ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisableLocked( 1362ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian const sp<SensorEventConnection>& connection, int handle) { 1363fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian SensorRecord* rec = mActiveSensors.valueFor(handle); 1364fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian if (rec) { 1365fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian // see if this connection becomes inactive 1366787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian if (connection->removeSensor(handle)) { 1367787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian BatteryService::disableSensor(connection->getUid(), handle); 1368787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian } 1369fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian if (connection->hasAnySensor() == false) { 13708a96955c8e14db40b16164236830fc9506a00872Aravind Akella connection->updateLooperRegistration(mLooper); 1371fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian mActiveConnections.remove(connection); 1372fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 1373fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian // see if this sensor becomes inactive 1374fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian if (rec->removeConnection(connection)) { 1375fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian mActiveSensors.removeItem(handle); 1376755c451c7861a029e26e5f16e319b629169e656dPeng Xu mActiveVirtualSensors.erase(handle); 1377fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian delete rec; 1378fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 13794342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh return NO_ERROR; 13807c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian } 13814342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh return BAD_VALUE; 1382fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 1383fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 13847c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianstatus_t SensorService::setEventRate(const sp<SensorEventConnection>& connection, 138547e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu int handle, nsecs_t ns, const String16& opPackageName) { 138650df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian if (mInitCheck != NO_ERROR) 138750df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian return mInitCheck; 138850df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian 1389755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 1390755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (sensor == nullptr || 1391755c451c7861a029e26e5f16e319b629169e656dPeng Xu !canAccessSensor(sensor->getSensor(), "Tried configuring", opPackageName)) { 1392700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return BAD_VALUE; 1393700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } 1394700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 13951cd700015318727d6d42236ab6274f1949fb08baMathias Agopian if (ns < 0) 13961cd700015318727d6d42236ab6274f1949fb08baMathias Agopian return BAD_VALUE; 13971cd700015318727d6d42236ab6274f1949fb08baMathias Agopian 139862569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs(); 139962569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian if (ns < minDelayNs) { 140062569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian ns = minDelayNs; 1401ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian } 1402ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian 1403f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian return sensor->setDelay(connection.get(), handle, ns); 1404fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 1405fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 1406b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslavstatus_t SensorService::flushSensor(const sp<SensorEventConnection>& connection, 1407b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav const String16& opPackageName) { 1408700180487ffec09d9df1657b018a7caadac24b75Aravind Akella if (mInitCheck != NO_ERROR) return mInitCheck; 14099e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella SensorDevice& dev(SensorDevice::getInstance()); 14109e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella const int halVersion = dev.getHalDeviceVersion(); 14119e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella status_t err(NO_ERROR); 14129e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella Mutex::Autolock _l(mLock); 14139e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // Loop through all sensors for this connection and call flush on each of them. 14149e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella for (size_t i = 0; i < connection->mSensorInfo.size(); ++i) { 14159e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella const int handle = connection->mSensorInfo.keyAt(i); 1416755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 1417755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (sensor == nullptr) { 1418755c451c7861a029e26e5f16e319b629169e656dPeng Xu continue; 1419755c451c7861a029e26e5f16e319b629169e656dPeng Xu } 14209e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) { 14219e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella ALOGE("flush called on a one-shot sensor"); 14229e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella err = INVALID_OPERATION; 14239e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella continue; 14249e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } 14258493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (halVersion <= SENSORS_DEVICE_API_VERSION_1_0 || isVirtualSensor(handle)) { 14269e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // For older devices just increment pending flush count which will send a trivial 14279e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // flush complete event. 14288a96955c8e14db40b16164236830fc9506a00872Aravind Akella connection->incrementPendingFlushCount(handle); 14299e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } else { 1430b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (!canAccessSensor(sensor->getSensor(), "Tried flushing", opPackageName)) { 1431b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav err = INVALID_OPERATION; 1432b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav continue; 1433b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav } 14349e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella status_t err_flush = sensor->flush(connection.get(), handle); 14359e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella if (err_flush == NO_ERROR) { 14369e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella SensorRecord* rec = mActiveSensors.valueFor(handle); 14379e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella if (rec != NULL) rec->addPendingFlushConnection(connection); 14389e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } 14399e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella err = (err_flush != NO_ERROR) ? err_flush : err; 14409e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } 14416c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } 14429e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella return err; 1443700180487ffec09d9df1657b018a7caadac24b75Aravind Akella} 1444700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 1445b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslavbool SensorService::canAccessSensor(const Sensor& sensor, const char* operation, 1446b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav const String16& opPackageName) { 1447b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav const String8& requiredPermission = sensor.getRequiredPermission(); 1448700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 1449b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (requiredPermission.length() <= 0) { 1450700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return true; 1451b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav } 1452b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav 1453b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav bool hasPermission = false; 1454b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav 1455b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav // Runtime permissions can't use the cache as they may change. 1456b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (sensor.isRequiredPermissionRuntime()) { 1457b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav hasPermission = checkPermission(String16(requiredPermission), 1458b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav IPCThreadState::self()->getCallingPid(), IPCThreadState::self()->getCallingUid()); 1459700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } else { 1460b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav hasPermission = PermissionCache::checkCallingPermission(String16(requiredPermission)); 1461b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav } 1462b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav 1463b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (!hasPermission) { 1464b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav ALOGE("%s a sensor (%s) without holding its required permission: %s", 1465b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav operation, sensor.getName().string(), sensor.getRequiredPermission().string()); 1466700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return false; 1467700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } 1468b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav 1469b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav const int32_t opCode = sensor.getRequiredAppOp(); 1470b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (opCode >= 0) { 1471b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav AppOpsManager appOps; 1472b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (appOps.noteOp(opCode, IPCThreadState::self()->getCallingUid(), opPackageName) 1473b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav != AppOpsManager::MODE_ALLOWED) { 1474d4036b6b7f9609fe09efabdbfbb8c8f9428f76f7Andreas Gampe ALOGE("%s a sensor (%s) without enabled required app op: %d", 1475b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav operation, sensor.getName().string(), opCode); 1476b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav return false; 1477b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav } 1478b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav } 1479b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav 1480b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav return true; 1481700180487ffec09d9df1657b018a7caadac24b75Aravind Akella} 1482700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 14839a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockState() { 14849a844cf78f09953145200b4074d47589257a408cAravind Akella Mutex::Autolock _l(mLock); 14859a844cf78f09953145200b4074d47589257a408cAravind Akella checkWakeLockStateLocked(); 14869a844cf78f09953145200b4074d47589257a408cAravind Akella} 14879a844cf78f09953145200b4074d47589257a408cAravind Akella 14889a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockStateLocked() { 14899a844cf78f09953145200b4074d47589257a408cAravind Akella if (!mWakeLockAcquired) { 14909a844cf78f09953145200b4074d47589257a408cAravind Akella return; 14919a844cf78f09953145200b4074d47589257a408cAravind Akella } 14929a844cf78f09953145200b4074d47589257a408cAravind Akella bool releaseLock = true; 14939a844cf78f09953145200b4074d47589257a408cAravind Akella for (size_t i=0 ; i<mActiveConnections.size() ; i++) { 14949a844cf78f09953145200b4074d47589257a408cAravind Akella sp<SensorEventConnection> connection(mActiveConnections[i].promote()); 14959a844cf78f09953145200b4074d47589257a408cAravind Akella if (connection != 0) { 14969a844cf78f09953145200b4074d47589257a408cAravind Akella if (connection->needsWakeLock()) { 14979a844cf78f09953145200b4074d47589257a408cAravind Akella releaseLock = false; 14989a844cf78f09953145200b4074d47589257a408cAravind Akella break; 14999a844cf78f09953145200b4074d47589257a408cAravind Akella } 15009a844cf78f09953145200b4074d47589257a408cAravind Akella } 15019a844cf78f09953145200b4074d47589257a408cAravind Akella } 15029a844cf78f09953145200b4074d47589257a408cAravind Akella if (releaseLock) { 1503b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella setWakeLockAcquiredLocked(false); 1504b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 1505b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella} 1506b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella 1507b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::sendEventsFromCache(const sp<SensorEventConnection>& connection) { 1508b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella Mutex::Autolock _l(mLock); 1509b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella connection->writeToSocketFromCache(); 1510b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (connection->needsWakeLock()) { 1511b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella setWakeLockAcquiredLocked(true); 1512b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 1513b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella} 1514b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella 1515b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::populateActiveConnections( 1516b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella SortedVector< sp<SensorEventConnection> >* activeConnections) { 1517b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella Mutex::Autolock _l(mLock); 1518b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella for (size_t i=0 ; i < mActiveConnections.size(); ++i) { 1519b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella sp<SensorEventConnection> connection(mActiveConnections[i].promote()); 1520b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (connection != 0) { 1521b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella activeConnections->add(connection); 1522b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 15239a844cf78f09953145200b4074d47589257a408cAravind Akella } 15249a844cf78f09953145200b4074d47589257a408cAravind Akella} 15256c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 15264949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akellabool SensorService::isWhiteListedPackage(const String8& packageName) { 1527841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella return (packageName.contains(mWhiteListedPackage.string())); 15284949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella} 15294949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella 1530e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xubool SensorService::isOperationRestricted(const String16& opPackageName) { 1531e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu Mutex::Autolock _l(mLock); 1532e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu if (mCurrentOperatingMode != RESTRICTED) { 1533e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu String8 package(opPackageName); 1534e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu return !isWhiteListedPackage(package); 1535e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 1536e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu return false; 1537e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu} 1538e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 1539fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}; // namespace android 1540