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> 2453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <openssl/digest.h> 2553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <openssl/hmac.h> 2653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <openssl/rand.h> 27dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu#include <sensor/SensorEventQueue.h> 28dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu#include <utils/SystemClock.h> 2953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 30787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian#include "BatteryService.h" 31984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "CorrectedGyroSensor.h" 32f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "GravitySensor.h" 33f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "LinearAccelerationSensor.h" 34984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "OrientationSensor.h" 35f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "RotationVectorSensor.h" 36984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "SensorFusion.h" 37755c451c7861a029e26e5f16e319b629169e656dPeng Xu#include "SensorInterface.h" 38eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu 39984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "SensorService.h" 40e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu#include "SensorDirectConnection.h" 41eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include "SensorEventAckReceiver.h" 426a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu#include "SensorEventConnection.h" 43eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include "SensorRecord.h" 44eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include "SensorRegistrationInfo.h" 45eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu 46eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <inttypes.h> 47eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <math.h> 4898d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu#include <sched.h> 49eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <stdint.h> 50eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <sys/socket.h> 5153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <sys/stat.h> 5253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <sys/types.h> 5353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <unistd.h> 54fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 55fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopiannamespace android { 56fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// --------------------------------------------------------------------------- 57fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 583301542828febc768e1df42892cfac4992c35474Mathias Agopian/* 593301542828febc768e1df42892cfac4992c35474Mathias Agopian * Notes: 603301542828febc768e1df42892cfac4992c35474Mathias Agopian * 613301542828febc768e1df42892cfac4992c35474Mathias Agopian * - what about a gyro-corrected magnetic-field sensor? 623301542828febc768e1df42892cfac4992c35474Mathias Agopian * - run mag sensor from time to time to force calibration 633301542828febc768e1df42892cfac4992c35474Mathias Agopian * - gravity sensor length is wrong (=> drift in linear-acc sensor) 643301542828febc768e1df42892cfac4992c35474Mathias Agopian * 653301542828febc768e1df42892cfac4992c35474Mathias Agopian */ 663301542828febc768e1df42892cfac4992c35474Mathias Agopian 678ef3c89eb2030395f8a342bd16dbb344957ab275Aravind Akellaconst char* SensorService::WAKE_LOCK_NAME = "SensorService_wakelock"; 6853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiseruint8_t SensorService::sHmacGlobalKey[128] = {}; 6953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiserbool SensorService::sHmacGlobalKeyIsValid = false; 7053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 7153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#define SENSOR_SERVICE_DIR "/data/system/sensor_service" 7253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#define SENSOR_SERVICE_HMAC_KEY_FILE SENSOR_SERVICE_DIR "/hmac_key" 7398d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu#define SENSOR_SERVICE_SCHED_FIFO_PRIORITY 10 7453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 75a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella// Permissions. 76dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xustatic const String16 sDumpPermission("android.permission.DUMP"); 77dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xustatic const String16 sLocationHardwarePermission("android.permission.LOCATION_HARDWARE"); 784342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 79fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorService() 808a96955c8e14db40b16164236830fc9506a00872Aravind Akella : mInitCheck(NO_INIT), mSocketBufferSize(SOCKET_BUFFER_SIZE_NON_BATCHED), 8147e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu mWakeLockAcquired(false) { 82fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 83fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 8453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiserbool SensorService::initializeHmacKey() { 8553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser int fd = open(SENSOR_SERVICE_HMAC_KEY_FILE, O_RDONLY|O_CLOEXEC); 8653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (fd != -1) { 8753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser int result = read(fd, sHmacGlobalKey, sizeof(sHmacGlobalKey)); 8853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser close(fd); 8953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (result == sizeof(sHmacGlobalKey)) { 9053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return true; 9153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 9253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser ALOGW("Unable to read HMAC key; generating new one."); 9353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 9453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 9553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (RAND_bytes(sHmacGlobalKey, sizeof(sHmacGlobalKey)) == -1) { 9653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser ALOGW("Can't generate HMAC key; dynamic sensor getId() will be wrong."); 9753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return false; 9853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 9953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 10053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // We need to make sure this is only readable to us. 10153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser bool wroteKey = false; 10253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser mkdir(SENSOR_SERVICE_DIR, S_IRWXU); 10353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser fd = open(SENSOR_SERVICE_HMAC_KEY_FILE, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, 10453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser S_IRUSR|S_IWUSR); 10553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (fd != -1) { 10653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser int result = write(fd, sHmacGlobalKey, sizeof(sHmacGlobalKey)); 10753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser close(fd); 10853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser wroteKey = (result == sizeof(sHmacGlobalKey)); 10953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 11053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (wroteKey) { 11153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser ALOGI("Generated new HMAC key."); 11253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } else { 11353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser ALOGW("Unable to write HMAC key; dynamic sensor getId() will change " 11453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser "after reboot."); 11553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 11653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Even if we failed to write the key we return true, because we did 11753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // initialize the HMAC key. 11853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return true; 11953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser} 12053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 12198d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu// Set main thread to SCHED_FIFO to lower sensor event latency when system is under load 12298d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xuvoid SensorService::enableSchedFifoMode() { 12398d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu struct sched_param param = {0}; 12498d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu param.sched_priority = SENSOR_SERVICE_SCHED_FIFO_PRIORITY; 12598d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu if (sched_setscheduler(getTid(), SCHED_FIFO | SCHED_RESET_ON_FORK, ¶m) != 0) { 12698d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu ALOGE("Couldn't set SCHED_FIFO for SensorService thread"); 12798d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu } 12898d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu} 12998d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu 13047e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xuvoid SensorService::onFirstRef() { 131a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block ALOGD("nuSensorService starting..."); 132f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian SensorDevice& dev(SensorDevice::getInstance()); 133fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 13453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser sHmacGlobalKeyIsValid = initializeHmacKey(); 13553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 136f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian if (dev.initCheck() == NO_ERROR) { 137f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sensor_t const* list; 1387b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian ssize_t count = dev.getSensorList(&list); 1397b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian if (count > 0) { 1407b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian ssize_t orientationIndex = -1; 141f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella bool hasGyro = false, hasAccel = false, hasMag = false; 1427b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian uint32_t virtualSensorsNeeds = 1437b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian (1<<SENSOR_TYPE_GRAVITY) | 1447b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian (1<<SENSOR_TYPE_LINEAR_ACCELERATION) | 145f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu (1<<SENSOR_TYPE_ROTATION_VECTOR) | 146f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR) | 147f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR); 1487b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian 1497b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian for (ssize_t i=0 ; i<count ; i++) { 150f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu bool useThisSensor=true; 151f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu 1527b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian switch (list[i].type) { 153f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella case SENSOR_TYPE_ACCELEROMETER: 154f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella hasAccel = true; 155f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella break; 156f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella case SENSOR_TYPE_MAGNETIC_FIELD: 157f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella hasMag = true; 158f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella break; 1597b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian case SENSOR_TYPE_ORIENTATION: 1607b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian orientationIndex = i; 1617b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian break; 1627b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian case SENSOR_TYPE_GYROSCOPE: 1630319306670b0344da99efa606b6f172dde575a39Mathias Agopian case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED: 1647b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian hasGyro = true; 1657b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian break; 1667b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian case SENSOR_TYPE_GRAVITY: 1677b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian case SENSOR_TYPE_LINEAR_ACCELERATION: 1687b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian case SENSOR_TYPE_ROTATION_VECTOR: 169f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR: 170f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu case SENSOR_TYPE_GAME_ROTATION_VECTOR: 171f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu if (IGNORE_HARDWARE_FUSION) { 172f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu useThisSensor = false; 173f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu } else { 174f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu virtualSensorsNeeds &= ~(1<<list[i].type); 175f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu } 1767b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian break; 1777b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian } 178f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu if (useThisSensor) { 179f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu registerSensor( new HardwareSensor(list[i]) ); 180f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu } 18150df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian } 182fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 1837b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian // it's safe to instantiate the SensorFusion object here 1847b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian // (it wants to be instantiated after h/w sensors have been 1857b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian // registered) 186d4036b6b7f9609fe09efabdbfbb8c8f9428f76f7Andreas Gampe SensorFusion::getInstance(); 1877b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian 188f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella if (hasGyro && hasAccel && hasMag) { 1890319306670b0344da99efa606b6f172dde575a39Mathias Agopian // Add Android virtual sensors if they're not already 1900319306670b0344da99efa606b6f172dde575a39Mathias Agopian // available in the HAL 1910cc8f809924706c7d683da30605f432635dd5bb6Peng Xu bool needRotationVector = 1920cc8f809924706c7d683da30605f432635dd5bb6Peng Xu (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) != 0; 1937b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian 1940cc8f809924706c7d683da30605f432635dd5bb6Peng Xu registerSensor(new RotationVectorSensor(), !needRotationVector, true); 1950cc8f809924706c7d683da30605f432635dd5bb6Peng Xu registerSensor(new OrientationSensor(), !needRotationVector, true); 196f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 1970cc8f809924706c7d683da30605f432635dd5bb6Peng Xu bool needLinearAcceleration = 1980cc8f809924706c7d683da30605f432635dd5bb6Peng Xu (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) != 0; 1990319306670b0344da99efa606b6f172dde575a39Mathias Agopian 2000cc8f809924706c7d683da30605f432635dd5bb6Peng Xu registerSensor(new LinearAccelerationSensor(list, count), 2010cc8f809924706c7d683da30605f432635dd5bb6Peng Xu !needLinearAcceleration, true); 202f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu 2030cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // virtual debugging sensors are not for user 204755c451c7861a029e26e5f16e319b629169e656dPeng Xu registerSensor( new CorrectedGyroSensor(list, count), true, true); 205755c451c7861a029e26e5f16e319b629169e656dPeng Xu registerSensor( new GyroDriftSensor(), true, true); 206010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian } 207010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian 208f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu if (hasAccel && hasGyro) { 2090cc8f809924706c7d683da30605f432635dd5bb6Peng Xu bool needGravitySensor = (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) != 0; 2100cc8f809924706c7d683da30605f432635dd5bb6Peng Xu registerSensor(new GravitySensor(list, count), !needGravitySensor, true); 211f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu 2120cc8f809924706c7d683da30605f432635dd5bb6Peng Xu bool needGameRotationVector = 2130cc8f809924706c7d683da30605f432635dd5bb6Peng Xu (virtualSensorsNeeds & (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR)) != 0; 2140cc8f809924706c7d683da30605f432635dd5bb6Peng Xu registerSensor(new GameRotationVectorSensor(), !needGameRotationVector, true); 215f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu } 216f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu 217f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu if (hasAccel && hasMag) { 2180cc8f809924706c7d683da30605f432635dd5bb6Peng Xu bool needGeoMagRotationVector = 2190cc8f809924706c7d683da30605f432635dd5bb6Peng Xu (virtualSensorsNeeds & (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR)) != 0; 2200cc8f809924706c7d683da30605f432635dd5bb6Peng Xu registerSensor(new GeoMagRotationVectorSensor(), !needGeoMagRotationVector, true); 221f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu } 222f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu 2235466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // Check if the device really supports batching by looking at the FIFO event 2245466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // counts for each sensor. 2255466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella bool batchingSupported = false; 2260cc8f809924706c7d683da30605f432635dd5bb6Peng Xu mSensors.forEachSensor( 2270cc8f809924706c7d683da30605f432635dd5bb6Peng Xu [&batchingSupported] (const Sensor& s) -> bool { 2280cc8f809924706c7d683da30605f432635dd5bb6Peng Xu if (s.getFifoMaxEventCount() > 0) { 2290cc8f809924706c7d683da30605f432635dd5bb6Peng Xu batchingSupported = true; 2300cc8f809924706c7d683da30605f432635dd5bb6Peng Xu } 2310cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return !batchingSupported; 2320cc8f809924706c7d683da30605f432635dd5bb6Peng Xu }); 2335466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella 2345466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella if (batchingSupported) { 2355466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // Increase socket buffer size to a max of 100 KB for batching capabilities. 2365466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella mSocketBufferSize = MAX_SOCKET_BUFFER_SIZE_BATCHED; 2375466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella } else { 2385466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella mSocketBufferSize = SOCKET_BUFFER_SIZE_NON_BATCHED; 2395466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella } 2405466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella 2415466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // Compare the socketBufferSize value against the system limits and limit 2425466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // it to maxSystemSocketBufferSize if necessary. 2434c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella FILE *fp = fopen("/proc/sys/net/core/wmem_max", "r"); 2444c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella char line[128]; 2454c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella if (fp != NULL && fgets(line, sizeof(line), fp) != NULL) { 2464c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella line[sizeof(line) - 1] = '\0'; 2475466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella size_t maxSystemSocketBufferSize; 2485466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella sscanf(line, "%zu", &maxSystemSocketBufferSize); 2495466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella if (mSocketBufferSize > maxSystemSocketBufferSize) { 2505466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella mSocketBufferSize = maxSystemSocketBufferSize; 2514c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 2524c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 2534c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella if (fp) { 2544c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella fclose(fp); 2554c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 2564c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella 2579a844cf78f09953145200b4074d47589257a408cAravind Akella mWakeLockAcquired = false; 25856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella mLooper = new Looper(false); 2598493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT; 2608493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mSensorEventBuffer = new sensors_event_t[minBufferSize]; 2618493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mSensorEventScratch = new sensors_event_t[minBufferSize]; 262eb05947ae2c4ac3a80712fed9382d82cb9aedad5Peng Xu mMapFlushEventsToConnections = new wp<const SensorEventConnection> [minBufferSize]; 263a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella mCurrentOperatingMode = NORMAL; 2647830ef3dd0ff3749d974c2dd85a8fa59dc47aecaAravind Akella 26518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mNextSensorRegIndex = 0; 26618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella for (int i = 0; i < SENSOR_REGISTRATIONS_BUF_SIZE; ++i) { 26718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mLastNSensorRegistrations.push(); 26818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } 26918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella 27018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mInitCheck = NO_ERROR; 271b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mAckReceiver = new SensorEventAckReceiver(this); 272b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY); 2737830ef3dd0ff3749d974c2dd85a8fa59dc47aecaAravind Akella run("SensorService", PRIORITY_URGENT_DISPLAY); 27498d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu 27598d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu // priority can only be changed after run 27698d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu enableSchedFifoMode(); 2777b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian } 278fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 279fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 280fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 2810cc8f809924706c7d683da30605f432635dd5bb6Peng Xuconst Sensor& SensorService::registerSensor(SensorInterface* s, bool isDebug, bool isVirtual) { 2820cc8f809924706c7d683da30605f432635dd5bb6Peng Xu int handle = s->getSensor().getHandle(); 2836a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu int type = s->getSensor().getType(); 2840cc8f809924706c7d683da30605f432635dd5bb6Peng Xu if (mSensors.add(handle, s, isDebug, isVirtual)){ 2856a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mRecentEvent.emplace(handle, new RecentEventLogger(type)); 2860cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return s->getSensor(); 2870cc8f809924706c7d683da30605f432635dd5bb6Peng Xu } else { 2880cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return mSensors.getNonSensor(); 2890cc8f809924706c7d683da30605f432635dd5bb6Peng Xu } 290f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian} 291f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 2926a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xuconst Sensor& SensorService::registerDynamicSensorLocked(SensorInterface* s, bool isDebug) { 2930cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return registerSensor(s, isDebug); 2942576cb63b3fe1592f54816625036566b9eb0793aPeng Xu} 2952576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 2966a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xubool SensorService::unregisterDynamicSensorLocked(int handle) { 2970cc8f809924706c7d683da30605f432635dd5bb6Peng Xu bool ret = mSensors.remove(handle); 2986a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 2996a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu const auto i = mRecentEvent.find(handle); 3006a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu if (i != mRecentEvent.end()) { 3016a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu delete i->second; 3026a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu mRecentEvent.erase(i); 3032576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 3040cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return ret; 305f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian} 306f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 3070cc8f809924706c7d683da30605f432635dd5bb6Peng Xuconst Sensor& SensorService::registerVirtualSensor(SensorInterface* s, bool isDebug) { 3080cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return registerSensor(s, isDebug, true); 30947e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu} 31047e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu 31147e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng XuSensorService::~SensorService() { 3126a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu for (auto && entry : mRecentEvent) { 3136a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu delete entry.second; 3146a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu } 315fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 316fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 31747e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xustatus_t SensorService::dump(int fd, const Vector<String16>& args) { 318fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian String8 result; 319dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu if (!PermissionCache::checkCallingPermission(sDumpPermission)) { 320eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu result.appendFormat("Permission Denial: can't dump SensorService from pid=%d, uid=%d\n", 321fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian IPCThreadState::self()->getCallingPid(), 322fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian IPCThreadState::self()->getCallingUid()); 323444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } else { 324fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu bool privileged = IPCThreadState::self()->getCallingUid() == 0; 325841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (args.size() > 2) { 3264949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella return INVALID_OPERATION; 3274949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella } 3284949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella Mutex::Autolock _l(mLock); 3294949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella SensorDevice& dev(SensorDevice::getInstance()); 330841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (args.size() == 2 && args[0] == String16("restrict")) { 331444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // If already in restricted mode. Ignore. 332444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (mCurrentOperatingMode == RESTRICTED) { 333444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella return status_t(NO_ERROR); 334444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 335444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // If in any mode other than normal, ignore. 336444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (mCurrentOperatingMode != NORMAL) { 337444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella return INVALID_OPERATION; 338444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 339e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 340a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella mCurrentOperatingMode = RESTRICTED; 341e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu // temporarily stop all sensor direct report 342e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu for (auto &i : mDirectConnections) { 343e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu sp<SensorDirectConnection> connection(i.promote()); 344e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu if (connection != nullptr) { 345e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu connection->stopAll(true /* backupRecord */); 346e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 347e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 348e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 3494949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella dev.disableAllSensors(); 3504949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella // Clear all pending flush connections for all active sensors. If one of the active 3514949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella // connections has called flush() and the underlying sensor has been disabled before a 3524949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella // flush complete event is returned, we need to remove the connection from this queue. 3534949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella for (size_t i=0 ; i< mActiveSensors.size(); ++i) { 3544949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella mActiveSensors.valueAt(i)->clearAllPendingFlushConnections(); 3554949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella } 356841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella mWhiteListedPackage.setTo(String8(args[1])); 357444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella return status_t(NO_ERROR); 358444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } else if (args.size() == 1 && args[0] == String16("enable")) { 359444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // If currently in restricted mode, reset back to NORMAL mode else ignore. 360444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (mCurrentOperatingMode == RESTRICTED) { 361444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella mCurrentOperatingMode = NORMAL; 362444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella dev.enableAllSensors(); 363e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu // recover all sensor direct report 364e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu for (auto &i : mDirectConnections) { 365e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu sp<SensorDirectConnection> connection(i.promote()); 366e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu if (connection != nullptr) { 367e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu connection->recoverAll(); 368e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 369e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 3706c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } 371841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (mCurrentOperatingMode == DATA_INJECTION) { 372841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella resetToNormalModeLocked(); 373841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } 374841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella mWhiteListedPackage.clear(); 375444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella return status_t(NO_ERROR); 376841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } else if (args.size() == 2 && args[0] == String16("data_injection")) { 377841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (mCurrentOperatingMode == NORMAL) { 378841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella dev.disableAllSensors(); 379841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella status_t err = dev.setMode(DATA_INJECTION); 380841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (err == NO_ERROR) { 381841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella mCurrentOperatingMode = DATA_INJECTION; 382841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } else { 383841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella // Re-enable sensors. 384841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella dev.enableAllSensors(); 385841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } 386841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella mWhiteListedPackage.setTo(String8(args[1])); 387841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella return NO_ERROR; 388841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } else if (mCurrentOperatingMode == DATA_INJECTION) { 389841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella // Already in DATA_INJECTION mode. Treat this as a no_op. 390841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella return NO_ERROR; 391841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } else { 392841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella // Transition to data injection mode supported only from NORMAL mode. 393841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella return INVALID_OPERATION; 394841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } 3950cc8f809924706c7d683da30605f432635dd5bb6Peng Xu } else if (!mSensors.hasAnySensor()) { 396ee155cadb23e84542cbf445c2aac89ae63df4cc7Aravind Akella result.append("No Sensors on the device\n"); 397444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } else { 398444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // Default dump the sensor list and debugging information. 3990cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // 4006a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu result.append("Sensor Device:\n"); 4016a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu result.append(SensorDevice::getInstance().dump().c_str()); 4026a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 4036a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu result.append("Sensor List:\n"); 4040cc8f809924706c7d683da30605f432635dd5bb6Peng Xu result.append(mSensors.dump().c_str()); 4056c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 4066a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu result.append("Fusion States:\n"); 407444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella SensorFusion::getInstance().dump(result); 408444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella 4090cc8f809924706c7d683da30605f432635dd5bb6Peng Xu result.append("Recent Sensor events:\n"); 4106a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu for (auto&& i : mRecentEvent) { 4116a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu sp<SensorInterface> s = mSensors.getInterface(i.first); 412fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu if (!i.second->isEmpty()) { 413fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu if (privileged || s->getSensor().getRequiredPermission().isEmpty()) { 414fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu i.second->setFormat("normal"); 415fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu } else { 416fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu i.second->setFormat("mask_data"); 417fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu } 4186a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu // if there is events and sensor does not need special permission. 4196a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu result.appendFormat("%s: ", s->getSensor().getName().string()); 4206a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu result.append(i.second->dump().c_str()); 4216a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu } 4226a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu } 4230cc8f809924706c7d683da30605f432635dd5bb6Peng Xu 424444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.append("Active sensors:\n"); 425444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella for (size_t i=0 ; i<mActiveSensors.size() ; i++) { 426444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella int handle = mActiveSensors.keyAt(i); 427444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat("%s (handle=0x%08x, connections=%zu)\n", 428444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella getSensorName(handle).string(), 429444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella handle, 430444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella mActiveSensors.valueAt(i)->getNumConnections()); 431ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian } 4324c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella 433d4036b6b7f9609fe09efabdbfbb8c8f9428f76f7Andreas Gampe result.appendFormat("Socket Buffer size = %zd events\n", 434444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella mSocketBufferSize/sizeof(sensors_event_t)); 43518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella result.appendFormat("WakeLock Status: %s \n", mWakeLockAcquired ? "acquired" : 43618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella "not held"); 437444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat("Mode :"); 438444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella switch(mCurrentOperatingMode) { 439444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella case NORMAL: 440444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat(" NORMAL\n"); 441444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella break; 442444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella case RESTRICTED: 443841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella result.appendFormat(" RESTRICTED : %s\n", mWhiteListedPackage.string()); 444444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella break; 445444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella case DATA_INJECTION: 446841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella result.appendFormat(" DATA_INJECTION : %s\n", mWhiteListedPackage.string()); 447444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 4484c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella 449e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu result.appendFormat("%zd active connections\n", mActiveConnections.size()); 450444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella for (size_t i=0 ; i < mActiveConnections.size() ; i++) { 451444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella sp<SensorEventConnection> connection(mActiveConnections[i].promote()); 452444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (connection != 0) { 453444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella result.appendFormat("Connection Number: %zu \n", i); 454444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella connection->dump(result); 455444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 4564c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 45718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella 458e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu result.appendFormat("%zd direct connections\n", mDirectConnections.size()); 459e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu for (size_t i = 0 ; i < mDirectConnections.size() ; i++) { 460e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu sp<SensorDirectConnection> connection(mDirectConnections[i].promote()); 461e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu if (connection != nullptr) { 462e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu result.appendFormat("Direct connection %zu:\n", i); 463e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu connection->dump(result); 464e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 465e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 466e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 46718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella result.appendFormat("Previous Registrations:\n"); 46818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella // Log in the reverse chronological order. 46918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella int currentIndex = (mNextSensorRegIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) % 47018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella SENSOR_REGISTRATIONS_BUF_SIZE; 47118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella const int startIndex = currentIndex; 47218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella do { 47318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella const SensorRegistrationInfo& reg_info = mLastNSensorRegistrations[currentIndex]; 47418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella if (SensorRegistrationInfo::isSentinel(reg_info)) { 47518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella // Ignore sentinel, proceed to next item. 47618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella currentIndex = (currentIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) % 47718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella SENSOR_REGISTRATIONS_BUF_SIZE; 47818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella continue; 47918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } 48051224681c9a80ff714d40c26d8f465fb1bae17e2Peng Xu result.appendFormat("%s\n", reg_info.dump().c_str()); 48118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella currentIndex = (currentIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) % 48218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella SENSOR_REGISTRATIONS_BUF_SIZE; 48318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } while(startIndex != currentIndex); 4844c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 485fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 486fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian write(fd, result.string(), result.size()); 487fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return NO_ERROR; 488fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 489fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 4900cc8f809924706c7d683da30605f432635dd5bb6Peng Xu//TODO: move to SensorEventConnection later 4919a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::cleanupAutoDisabledSensorLocked(const sp<SensorEventConnection>& connection, 4924342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh sensors_event_t const* buffer, const int count) { 4934342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh for (int i=0 ; i<count ; i++) { 4944342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh int handle = buffer[i].sensor; 4958493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (buffer[i].type == SENSOR_TYPE_META_DATA) { 4968493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella handle = buffer[i].meta_data.sensor; 4978493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } 4980e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella if (connection->hasSensor(handle)) { 499755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> si = getSensorInterfaceFromHandle(handle); 5000e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella // If this buffer has an event from a one_shot sensor and this connection is registered 5010e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella // for this particular one_shot sensor, try cleaning up the connection. 502755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (si != nullptr && 5030cc8f809924706c7d683da30605f432635dd5bb6Peng Xu si->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) { 5040cc8f809924706c7d683da30605f432635dd5bb6Peng Xu si->autoDisable(connection.get(), handle); 5059a844cf78f09953145200b4074d47589257a408cAravind Akella cleanupWithoutDisableLocked(connection, handle); 5064342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 507a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella 5084342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 509a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella } 5104342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh} 5114342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 51247e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xubool SensorService::threadLoop() { 513a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block ALOGD("nuSensorService thread starting..."); 514fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 515eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // each virtual sensor could generate an event per "real" event, that's why we need to size 516eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT. in practice, this is too 517eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // aggressive, but guaranteed to be enough. 5180cc8f809924706c7d683da30605f432635dd5bb6Peng Xu const size_t vcount = mSensors.getVirtualSensors().size(); 51990ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT; 5200cc8f809924706c7d683da30605f432635dd5bb6Peng Xu const size_t numEventMax = minBufferSize / (1 + vcount); 52190ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian 522f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian SensorDevice& device(SensorDevice::getInstance()); 523fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 5244342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh const int halVersion = device.getHalDeviceVersion(); 525fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian do { 5268493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella ssize_t count = device.poll(mSensorEventBuffer, numEventMax); 5278493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (count < 0) { 528f5a1230d322c14c42331d0a1536b50c87742973bSteve Block ALOGE("sensor poll failed (%s)", strerror(-count)); 529fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian break; 530fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 53156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 53256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // Reset sensors_event_t.flags to zero for all events in the buffer. 53356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella for (int i = 0; i < count; i++) { 5348493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mSensorEventBuffer[i].flags = 0; 53556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 536e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella 537eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // Make a copy of the connection vector as some connections may be removed during the course 538eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // of this loop (especially when one-shot sensor events are present in the sensor_event 539eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // buffer). Promote all connections to StrongPointers before the lock is acquired. If the 540eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // destructor of the sp gets called when the lock is acquired, it may result in a deadlock 541eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // as ~SensorEventConnection() needs to acquire mLock again for cleanup. So copy all the 542eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu // strongPointers to a vector before the lock is acquired. 543e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella SortedVector< sp<SensorEventConnection> > activeConnections; 544b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella populateActiveConnections(&activeConnections); 545eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu 5469a844cf78f09953145200b4074d47589257a408cAravind Akella Mutex::Autolock _l(mLock); 5479a844cf78f09953145200b4074d47589257a408cAravind Akella // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The 5489a844cf78f09953145200b4074d47589257a408cAravind Akella // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock, 5499a844cf78f09953145200b4074d47589257a408cAravind Akella // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should 5509a844cf78f09953145200b4074d47589257a408cAravind Akella // not be interleaved with decrementing SensorEventConnection::mWakeLockRefCount and 5519a844cf78f09953145200b4074d47589257a408cAravind Akella // releasing the wakelock. 5529a844cf78f09953145200b4074d47589257a408cAravind Akella bool bufferHasWakeUpEvent = false; 5534342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh for (int i = 0; i < count; i++) { 5548493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (isWakeUpSensorEvent(mSensorEventBuffer[i])) { 5559a844cf78f09953145200b4074d47589257a408cAravind Akella bufferHasWakeUpEvent = true; 5569a844cf78f09953145200b4074d47589257a408cAravind Akella break; 5574342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 5584342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 5594342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 5609a844cf78f09953145200b4074d47589257a408cAravind Akella if (bufferHasWakeUpEvent && !mWakeLockAcquired) { 561b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella setWakeLockAcquiredLocked(true); 5629a844cf78f09953145200b4074d47589257a408cAravind Akella } 5638493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella recordLastValueLocked(mSensorEventBuffer, count); 56494e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian 565f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian // handle virtual sensors 566f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian if (count && vcount) { 5678493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella sensors_event_t const * const event = mSensorEventBuffer; 568755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (!mActiveVirtualSensors.empty()) { 569f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian size_t k = 0; 570984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian SensorFusion& fusion(SensorFusion::getInstance()); 571984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian if (fusion.isEnabled()) { 572984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t i=0 ; i<size_t(count) ; i++) { 573984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian fusion.process(event[i]); 574984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 575984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 576d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) { 577755c451c7861a029e26e5f16e319b629169e656dPeng Xu for (int handle : mActiveVirtualSensors) { 578d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian if (count + k >= minBufferSize) { 579d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian ALOGE("buffer too small to hold all events: " 580db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn "count=%zd, k=%zu, size=%zu", 581d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian count, k, minBufferSize); 582d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian break; 583d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian } 584f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sensors_event_t out; 585755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> si = mSensors.getInterface(handle); 586755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (si == nullptr) { 587755c451c7861a029e26e5f16e319b629169e656dPeng Xu ALOGE("handle %d is not an valid virtual sensor", handle); 588755c451c7861a029e26e5f16e319b629169e656dPeng Xu continue; 589755c451c7861a029e26e5f16e319b629169e656dPeng Xu } 590755c451c7861a029e26e5f16e319b629169e656dPeng Xu 591d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian if (si->process(&out, event[i])) { 5928493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mSensorEventBuffer[count + k] = out; 593f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian k++; 594f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 595f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 596f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 597f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian if (k) { 598f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian // record the last synthesized values 5998493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella recordLastValueLocked(&mSensorEventBuffer[count], k); 600f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian count += k; 601f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian // sort the buffer by time-stamps 6028493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella sortEventBuffer(mSensorEventBuffer, count); 603f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 604f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 605f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 606f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 6074342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // handle backward compatibility for RotationVector sensor 6084342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) { 6094342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh for (int i = 0; i < count; i++) { 6108493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (mSensorEventBuffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) { 6114342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // All the 4 components of the quaternion should be available 6124342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // No heading accuracy. Set it to -1 6138493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mSensorEventBuffer[i].data[4] = -1; 6148493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } 6158493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } 6168493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } 6178493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella 6188493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella for (int i = 0; i < count; ++i) { 6190cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // Map flush_complete_events in the buffer to SensorEventConnections which called flush 6200cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // on the hardware sensor. mapFlushEventsToConnections[i] will be the 6210cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // SensorEventConnection mapped to the corresponding flush_complete_event in 6220cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // mSensorEventBuffer[i] if such a mapping exists (NULL otherwise). 6238493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mMapFlushEventsToConnections[i] = NULL; 6248493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (mSensorEventBuffer[i].type == SENSOR_TYPE_META_DATA) { 6258493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella const int sensor_handle = mSensorEventBuffer[i].meta_data.sensor; 6268493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella SensorRecord* rec = mActiveSensors.valueFor(sensor_handle); 6278493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (rec != NULL) { 6288493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mMapFlushEventsToConnections[i] = rec->getFirstPendingFlushConnection(); 6298493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella rec->removeFirstPendingFlushConnection(); 6304342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 6314342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 6322576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 6332576cb63b3fe1592f54816625036566b9eb0793aPeng Xu // handle dynamic sensor meta events, process registration and unregistration of dynamic 6342576cb63b3fe1592f54816625036566b9eb0793aPeng Xu // sensor based on content of event. 6352576cb63b3fe1592f54816625036566b9eb0793aPeng Xu if (mSensorEventBuffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META) { 6362576cb63b3fe1592f54816625036566b9eb0793aPeng Xu if (mSensorEventBuffer[i].dynamic_sensor_meta.connected) { 6372576cb63b3fe1592f54816625036566b9eb0793aPeng Xu int handle = mSensorEventBuffer[i].dynamic_sensor_meta.handle; 6382576cb63b3fe1592f54816625036566b9eb0793aPeng Xu const sensor_t& dynamicSensor = 6392576cb63b3fe1592f54816625036566b9eb0793aPeng Xu *(mSensorEventBuffer[i].dynamic_sensor_meta.sensor); 6402576cb63b3fe1592f54816625036566b9eb0793aPeng Xu ALOGI("Dynamic sensor handle 0x%x connected, type %d, name %s", 6412576cb63b3fe1592f54816625036566b9eb0793aPeng Xu handle, dynamicSensor.type, dynamicSensor.name); 6422576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 6430cc8f809924706c7d683da30605f432635dd5bb6Peng Xu if (mSensors.isNewHandle(handle)) { 6446a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu const auto& uuid = mSensorEventBuffer[i].dynamic_sensor_meta.uuid; 64547e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu sensor_t s = dynamicSensor; 64647e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu // make sure the dynamic sensor flag is set 64747e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu s.flags |= DYNAMIC_SENSOR_MASK; 64847e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu // force the handle to be consistent 64947e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu s.handle = handle; 6506a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 6516a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu SensorInterface *si = new HardwareSensor(s, uuid); 65247e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu 6530cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // This will release hold on dynamic sensor meta, so it should be called 6540cc8f809924706c7d683da30605f432635dd5bb6Peng Xu // after Sensor object is created. 65547e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu device.handleDynamicSensorConnection(handle, true /*connected*/); 6566a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu registerDynamicSensorLocked(si); 65747e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu } else { 65847e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu ALOGE("Handle %d has been used, cannot use again before reboot.", handle); 65947e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu } 6602576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } else { 6612576cb63b3fe1592f54816625036566b9eb0793aPeng Xu int handle = mSensorEventBuffer[i].dynamic_sensor_meta.handle; 6622576cb63b3fe1592f54816625036566b9eb0793aPeng Xu ALOGI("Dynamic sensor handle 0x%x disconnected", handle); 6632576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 6642576cb63b3fe1592f54816625036566b9eb0793aPeng Xu device.handleDynamicSensorConnection(handle, false /*connected*/); 6656a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu if (!unregisterDynamicSensorLocked(handle)) { 6662576cb63b3fe1592f54816625036566b9eb0793aPeng Xu ALOGE("Dynamic sensor release error."); 6672576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 6682576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 6692576cb63b3fe1592f54816625036566b9eb0793aPeng Xu size_t numConnections = activeConnections.size(); 6702576cb63b3fe1592f54816625036566b9eb0793aPeng Xu for (size_t i=0 ; i < numConnections; ++i) { 6712576cb63b3fe1592f54816625036566b9eb0793aPeng Xu if (activeConnections[i] != NULL) { 6722576cb63b3fe1592f54816625036566b9eb0793aPeng Xu activeConnections[i]->removeSensor(handle); 6732576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 6742576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 6752576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 6762576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 6774342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 6784342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 6792576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 6809a844cf78f09953145200b4074d47589257a408cAravind Akella // Send our events to clients. Check the state of wake lock for each client and release the 6819a844cf78f09953145200b4074d47589257a408cAravind Akella // lock if none of the clients need it. 6829a844cf78f09953145200b4074d47589257a408cAravind Akella bool needsWakeLock = false; 6838493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella size_t numConnections = activeConnections.size(); 6848493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella for (size_t i=0 ; i < numConnections; ++i) { 685e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella if (activeConnections[i] != 0) { 686e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch, 6878493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella mMapFlushEventsToConnections); 688e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella needsWakeLock |= activeConnections[i]->needsWakeLock(); 6898493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella // If the connection has one-shot sensors, it may be cleaned up after first trigger. 6908493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella // Early check for one-shot sensors. 691e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella if (activeConnections[i]->hasOneShotSensors()) { 692e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer, 693e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella count); 6948493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } 695fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 696fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 6974342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 6989a844cf78f09953145200b4074d47589257a408cAravind Akella if (mWakeLockAcquired && !needsWakeLock) { 699b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella setWakeLockAcquiredLocked(false); 7009a844cf78f09953145200b4074d47589257a408cAravind Akella } 7018493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella } while (!Thread::exitPending()); 702fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 7033c20fbed7f3a916ced10f2ed5a272271b7d81edeSteve Block ALOGW("Exiting SensorService::threadLoop => aborting..."); 7041a62301fc58cd2af18239b0415813461bf5fc41bMathias Agopian abort(); 705fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return false; 706fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 707fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 70856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellasp<Looper> SensorService::getLooper() const { 70956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella return mLooper; 71056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella} 71156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 712b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::resetAllWakeLockRefCounts() { 713b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella SortedVector< sp<SensorEventConnection> > activeConnections; 714b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella populateActiveConnections(&activeConnections); 715b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella { 716b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella Mutex::Autolock _l(mLock); 717b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella for (size_t i=0 ; i < activeConnections.size(); ++i) { 718b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (activeConnections[i] != 0) { 719b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella activeConnections[i]->resetWakeLockRefCount(); 720b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 721b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 722b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella setWakeLockAcquiredLocked(false); 723b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 724b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella} 725b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella 726b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::setWakeLockAcquiredLocked(bool acquire) { 727b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (acquire) { 728b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (!mWakeLockAcquired) { 729b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME); 730b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mWakeLockAcquired = true; 731b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 732b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mLooper->wake(); 733b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } else { 734b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (mWakeLockAcquired) { 735b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella release_wake_lock(WAKE_LOCK_NAME); 736b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mWakeLockAcquired = false; 737b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 738b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 739b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella} 740b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella 741b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellabool SensorService::isWakeLockAcquired() { 742b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella Mutex::Autolock _l(mLock); 743b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella return mWakeLockAcquired; 744b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella} 745b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella 74656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellabool SensorService::SensorEventAckReceiver::threadLoop() { 74756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella ALOGD("new thread SensorEventAckReceiver"); 748b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella sp<Looper> looper = mService->getLooper(); 74956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella do { 750b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella bool wakeLockAcquired = mService->isWakeLockAcquired(); 751b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella int timeout = -1; 752b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (wakeLockAcquired) timeout = 5000; 753b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella int ret = looper->pollOnce(timeout); 754b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (ret == ALOOPER_POLL_TIMEOUT) { 755b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella mService->resetAllWakeLockRefCounts(); 756b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 75756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } while(!Thread::exitPending()); 75856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella return false; 75956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella} 76056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 7619a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::recordLastValueLocked( 7624b84704b97300eff3ebfab85652e64d54149d205Aravind Akella const sensors_event_t* buffer, size_t count) { 7634b84704b97300eff3ebfab85652e64d54149d205Aravind Akella for (size_t i = 0; i < count; i++) { 7642576cb63b3fe1592f54816625036566b9eb0793aPeng Xu if (buffer[i].type == SENSOR_TYPE_META_DATA || 7652576cb63b3fe1592f54816625036566b9eb0793aPeng Xu buffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META || 7666a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO) { 7672576cb63b3fe1592f54816625036566b9eb0793aPeng Xu continue; 7682576cb63b3fe1592f54816625036566b9eb0793aPeng Xu } 7692576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 7706a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu auto logger = mRecentEvent.find(buffer[i].sensor); 7716a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu if (logger != mRecentEvent.end()) { 7726a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu logger->second->addEvent(buffer[i]); 77394e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian } 77494e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian } 77594e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian} 77694e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian 77747e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xuvoid SensorService::sortEventBuffer(sensors_event_t* buffer, size_t count) { 778f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian struct compar { 779f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian static int cmp(void const* lhs, void const* rhs) { 780f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sensors_event_t const* l = static_cast<sensors_event_t const*>(lhs); 781f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sensors_event_t const* r = static_cast<sensors_event_t const*>(rhs); 782a5c106a4f0afcf061728a1cb7c8c3b908728575dMathias Agopian return l->timestamp - r->timestamp; 783f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 784f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian }; 785f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian qsort(buffer, count, sizeof(sensors_event_t), compar::cmp); 786f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian} 787f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 7885d2707214dfb97bd8dfcc6620be36841d3c82420Mathias AgopianString8 SensorService::getSensorName(int handle) const { 7890cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return mSensors.getName(handle); 7905d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian} 7915d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian 792b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akellabool SensorService::isVirtualSensor(int handle) const { 793755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 794755c451c7861a029e26e5f16e319b629169e656dPeng Xu return sensor != nullptr && sensor->isVirtual(); 795b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella} 796b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella 7979a844cf78f09953145200b4074d47589257a408cAravind Akellabool SensorService::isWakeUpSensorEvent(const sensors_event_t& event) const { 7987869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan int handle = event.sensor; 7997869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan if (event.type == SENSOR_TYPE_META_DATA) { 8007869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan handle = event.meta_data.sensor; 8017869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan } 802755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 803755c451c7861a029e26e5f16e319b629169e656dPeng Xu return sensor != nullptr && sensor->getSensor().isWakeUpSensor(); 8049a844cf78f09953145200b4074d47589257a408cAravind Akella} 8059a844cf78f09953145200b4074d47589257a408cAravind Akella 80653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiserint32_t SensorService::getIdFromUuid(const Sensor::uuid_t &uuid) const { 80753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if ((uuid.i64[0] == 0) && (uuid.i64[1] == 0)) { 80853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // UUID is not supported for this device. 80953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return 0; 81053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 81153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if ((uuid.i64[0] == INT64_C(~0)) && (uuid.i64[1] == INT64_C(~0))) { 81253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // This sensor can be uniquely identified in the system by 81353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // the combination of its type and name. 81453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return -1; 81553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 81653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 81753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // We have a dynamic sensor. 81853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 81953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (!sHmacGlobalKeyIsValid) { 82053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Rather than risk exposing UUIDs, we cripple dynamic sensors. 82153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser ALOGW("HMAC key failure; dynamic sensor getId() will be wrong."); 82253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return 0; 82353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 82453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 82553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // We want each app author/publisher to get a different ID, so that the 82653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // same dynamic sensor cannot be tracked across apps by multiple 82753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // authors/publishers. So we use both our UUID and our User ID. 82853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Note potential confusion: 82953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // UUID => Universally Unique Identifier. 83053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // UID => User Identifier. 83153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // We refrain from using "uid" except as needed by API to try to 83253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // keep this distinction clear. 83353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 83453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser auto appUserId = IPCThreadState::self()->getCallingUid(); 83553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser uint8_t uuidAndApp[sizeof(uuid) + sizeof(appUserId)]; 83653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser memcpy(uuidAndApp, &uuid, sizeof(uuid)); 83753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser memcpy(uuidAndApp + sizeof(uuid), &appUserId, sizeof(appUserId)); 83853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 83953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Now we use our key on our UUID/app combo to get the hash. 84053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser uint8_t hash[EVP_MAX_MD_SIZE]; 84153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser unsigned int hashLen; 84253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (HMAC(EVP_sha256(), 84353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser sHmacGlobalKey, sizeof(sHmacGlobalKey), 84453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser uuidAndApp, sizeof(uuidAndApp), 84553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser hash, &hashLen) == nullptr) { 84653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Rather than risk exposing UUIDs, we cripple dynamic sensors. 84753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser ALOGW("HMAC failure; dynamic sensor getId() will be wrong."); 84853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return 0; 84953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 85053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 85153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser int32_t id = 0; 85253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (hashLen < sizeof(id)) { 85353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // We never expect this case, but out of paranoia, we handle it. 85453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Our 'id' length is already quite small, we don't want the 85553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // effective length of it to be even smaller. 85653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Rather than risk exposing UUIDs, we cripple dynamic sensors. 85753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser ALOGW("HMAC insufficient; dynamic sensor getId() will be wrong."); 85853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return 0; 85953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 86053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 86153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // This is almost certainly less than all of 'hash', but it's as secure 86253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // as we can be with our current 'id' length. 86353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser memcpy(&id, hash, sizeof(id)); 86453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 86553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // Note at the beginning of the function that we return the values of 86653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // 0 and -1 to represent special cases. As a result, we can't return 86753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // those as dynamic sensor IDs. If we happened to hash to one of those 86853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // values, we change 'id' so we report as a dynamic sensor, and not as 86953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser // one of those special cases. 87053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser if (id == -1) { 87153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser id = -2; 87253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } else if (id == 0) { 87353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser id = 1; 87453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 87553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser return id; 87653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser} 87753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 87853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiservoid SensorService::makeUuidsIntoIdsForSensorList(Vector<Sensor> &sensorList) const { 87953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser for (auto &sensor : sensorList) { 88053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser int32_t id = getIdFromUuid(sensor.getUuid()); 88153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser sensor.setId(id); 88253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser } 88353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser} 88453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser 8852c588c536090ea3e7e80db0e5031935b6026814cNick VaccaroVector<Sensor> SensorService::getSensorList(const String16& /* opPackageName */) { 88633264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian char value[PROPERTY_VALUE_MAX]; 88733264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian property_get("debug.sensors", value, "0"); 888700180487ffec09d9df1657b018a7caadac24b75Aravind Akella const Vector<Sensor>& initialSensorList = (atoi(value)) ? 8890cc8f809924706c7d683da30605f432635dd5bb6Peng Xu mSensors.getUserDebugSensors() : mSensors.getUserSensors(); 890700180487ffec09d9df1657b018a7caadac24b75Aravind Akella Vector<Sensor> accessibleSensorList; 891700180487ffec09d9df1657b018a7caadac24b75Aravind Akella for (size_t i = 0; i < initialSensorList.size(); i++) { 892700180487ffec09d9df1657b018a7caadac24b75Aravind Akella Sensor sensor = initialSensorList[i]; 8932c588c536090ea3e7e80db0e5031935b6026814cNick Vaccaro accessibleSensorList.add(sensor); 89433264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian } 89553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser makeUuidsIntoIdsForSensorList(accessibleSensorList); 896700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return accessibleSensorList; 897fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 898fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 89947e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng XuVector<Sensor> SensorService::getDynamicSensorList(const String16& opPackageName) { 9002576cb63b3fe1592f54816625036566b9eb0793aPeng Xu Vector<Sensor> accessibleSensorList; 9010cc8f809924706c7d683da30605f432635dd5bb6Peng Xu mSensors.forEachSensor( 9020cc8f809924706c7d683da30605f432635dd5bb6Peng Xu [&opPackageName, &accessibleSensorList] (const Sensor& sensor) -> bool { 903755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (sensor.isDynamicSensor()) { 904755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (canAccessSensor(sensor, "getDynamicSensorList", opPackageName)) { 905755c451c7861a029e26e5f16e319b629169e656dPeng Xu accessibleSensorList.add(sensor); 906755c451c7861a029e26e5f16e319b629169e656dPeng Xu } else { 907755c451c7861a029e26e5f16e319b629169e656dPeng Xu ALOGI("Skipped sensor %s because it requires permission %s and app op %" PRId32, 908755c451c7861a029e26e5f16e319b629169e656dPeng Xu sensor.getName().string(), 909755c451c7861a029e26e5f16e319b629169e656dPeng Xu sensor.getRequiredPermission().string(), 910755c451c7861a029e26e5f16e319b629169e656dPeng Xu sensor.getRequiredAppOp()); 911755c451c7861a029e26e5f16e319b629169e656dPeng Xu } 9120cc8f809924706c7d683da30605f432635dd5bb6Peng Xu } 9130cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return true; 9140cc8f809924706c7d683da30605f432635dd5bb6Peng Xu }); 91553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser makeUuidsIntoIdsForSensorList(accessibleSensorList); 9162576cb63b3fe1592f54816625036566b9eb0793aPeng Xu return accessibleSensorList; 9172576cb63b3fe1592f54816625036566b9eb0793aPeng Xu} 9182576cb63b3fe1592f54816625036566b9eb0793aPeng Xu 919a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellasp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName, 920b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav int requestedMode, const String16& opPackageName) { 921a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella // Only 2 modes supported for a SensorEventConnection ... NORMAL and DATA_INJECTION. 922a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella if (requestedMode != NORMAL && requestedMode != DATA_INJECTION) { 923a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella return NULL; 924a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella } 925a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella 926a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella Mutex::Autolock _l(mLock); 927841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella // To create a client in DATA_INJECTION mode to inject data, SensorService should already be 928841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella // operating in DI mode. 929841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (requestedMode == DATA_INJECTION) { 930841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (mCurrentOperatingMode != DATA_INJECTION) return NULL; 931841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella if (!isWhiteListedPackage(packageName)) return NULL; 932841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella } 933841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella 9345307d17fe33fc26eeeacd6339a9fbfe96cf56873Mathias Agopian uid_t uid = IPCThreadState::self()->getCallingUid(); 935a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella sp<SensorEventConnection> result(new SensorEventConnection(this, uid, packageName, 936b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav requestedMode == DATA_INJECTION, opPackageName)); 937a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella if (requestedMode == DATA_INJECTION) { 938a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella if (mActiveConnections.indexOf(result) < 0) { 939a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella mActiveConnections.add(result); 940a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella } 941a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella // Add the associated file descriptor to the Looper for polling whenever there is data to 942a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella // be injected. 943a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella result->updateLooperRegistration(mLooper); 944a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella } 945fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return result; 946fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 947fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 948841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akellaint SensorService::isDataInjectionEnabled() { 949a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella Mutex::Autolock _l(mLock); 950841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella return (mCurrentOperatingMode == DATA_INJECTION); 951a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella} 952a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella 953e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xusp<ISensorEventConnection> SensorService::createSensorDirectConnection( 954e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu const String16& opPackageName, uint32_t size, int32_t type, int32_t format, 955e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu const native_handle *resource) { 956e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu Mutex::Autolock _l(mLock); 957e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 958e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu struct sensors_direct_mem_t mem = { 959e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu .type = type, 960e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu .format = format, 961e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu .size = size, 962e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu .handle = resource, 963e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu }; 964e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu uid_t uid = IPCThreadState::self()->getCallingUid(); 965e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 966e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu if (mem.handle == nullptr) { 967e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu ALOGE("Failed to clone resource handle"); 968e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu return nullptr; 969e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 970e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 971e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu // check format 972e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu if (format != SENSOR_DIRECT_FMT_SENSORS_EVENT) { 973e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu ALOGE("Direct channel format %d is unsupported!", format); 974e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu return nullptr; 975e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 976e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 977e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu // check for duplication 978e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu for (auto &i : mDirectConnections) { 979e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu sp<SensorDirectConnection> connection(i.promote()); 980e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu if (connection != nullptr && connection->isEquivalent(&mem)) { 981f88e2b95b2cd6238f6758ef6a180fbd277f06ff2Peng Xu ALOGE("Duplicate create channel request for the same share memory"); 982e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu return nullptr; 983e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 984e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 985e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 986e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu // check specific to memory type 987e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu switch(type) { 988e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu case SENSOR_DIRECT_MEM_TYPE_ASHMEM: { // channel backed by ashmem 989e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu int fd = resource->data[0]; 990e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu int size2 = ashmem_get_size_region(fd); 991e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu // check size consistency 992f88e2b95b2cd6238f6758ef6a180fbd277f06ff2Peng Xu if (size2 < static_cast<int>(size)) { 993f88e2b95b2cd6238f6758ef6a180fbd277f06ff2Peng Xu ALOGE("Ashmem direct channel size %" PRIu32 " greater than shared memory size %d", 994f88e2b95b2cd6238f6758ef6a180fbd277f06ff2Peng Xu size, size2); 995e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu return nullptr; 996e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 997e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu break; 998e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 999e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu case SENSOR_DIRECT_MEM_TYPE_GRALLOC: 1000f88e2b95b2cd6238f6758ef6a180fbd277f06ff2Peng Xu // no specific checks for gralloc 1001e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu break; 1002e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu default: 1003e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu ALOGE("Unknown direct connection memory type %d", type); 1004e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu return nullptr; 1005e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 1006e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 1007e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu native_handle_t *clone = native_handle_clone(resource); 1008e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu if (!clone) { 1009e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu return nullptr; 1010e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 1011e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 1012e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu SensorDirectConnection* conn = nullptr; 1013e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu SensorDevice& dev(SensorDevice::getInstance()); 1014e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu int channelHandle = dev.registerDirectChannel(&mem); 1015e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 1016e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu if (channelHandle <= 0) { 1017e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu ALOGE("SensorDevice::registerDirectChannel returns %d", channelHandle); 1018e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } else { 1019e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu mem.handle = clone; 1020e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu conn = new SensorDirectConnection(this, uid, &mem, channelHandle, opPackageName); 1021e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 1022e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 1023e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu if (conn == nullptr) { 1024e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu native_handle_close(clone); 1025e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu native_handle_delete(clone); 1026e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } else { 1027e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu // add to list of direct connections 1028e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu // sensor service should never hold pointer or sp of SensorDirectConnection object. 1029e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu mDirectConnections.add(wp<SensorDirectConnection>(conn)); 1030e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 1031e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu return conn; 1032e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu} 1033e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 1034dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xuint SensorService::setOperationParameter( 1035dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu int32_t type, const Vector<float> &floats, const Vector<int32_t> &ints) { 1036dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu Mutex::Autolock _l(mLock); 1037dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu 1038dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu // check permission 1039dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu int32_t uid; 1040dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu bool hasPermission = checkCallingPermission(sLocationHardwarePermission, nullptr, &uid); 1041dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu if (!hasPermission || (uid != 1000 && uid != 0)) { 1042dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu return PERMISSION_DENIED; 1043dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu } 1044dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu 1045dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu bool isFloat = true; 1046dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu size_t expectSize = INT32_MAX; 1047dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu switch (type) { 1048dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu case AINFO_LOCAL_GEOMAGNETIC_FIELD: 1049dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu isFloat = true; 1050dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu expectSize = 3; 1051dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu break; 1052dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu case AINFO_LOCAL_GRAVITY: 1053dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu isFloat = true; 1054dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu expectSize = 1; 1055dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu break; 1056dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu case AINFO_DOCK_STATE: 1057dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu case AINFO_HIGH_PERFORMANCE_MODE: 1058dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu case AINFO_MAGNETIC_FIELD_CALIBRATION: 1059dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu isFloat = false; 1060dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu expectSize = 1; 1061dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu break; 1062dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu default: 1063dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu return BAD_VALUE; 1064dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu } 1065dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu 1066dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu // three events: first one is begin tag, last one is end tag, the one in the middle 1067dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu // is the payload. 1068dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu sensors_event_t event[3]; 1069dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu int64_t timestamp = elapsedRealtimeNano(); 1070dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu for (sensors_event_t* i = event; i < event + 3; i++) { 1071dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu *i = (sensors_event_t) { 1072dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu .version = sizeof(sensors_event_t), 1073380b8ba38aacc53cbe29219fd7c41a5b0e22081fPeng Xu .sensor = SENSORS_HANDLE_BASE - 1, // sensor that never exists 1074dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu .type = SENSOR_TYPE_ADDITIONAL_INFO, 1075dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu .timestamp = timestamp++, 1076dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu .additional_info = (additional_info_event_t) { 1077dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu .serial = 0 1078dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu } 1079dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu }; 1080dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu } 1081dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu 1082dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu event[0].additional_info.type = AINFO_BEGIN; 1083dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu event[1].additional_info.type = type; 1084dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu event[2].additional_info.type = AINFO_END; 1085dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu 1086dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu if (isFloat) { 1087dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu if (floats.size() != expectSize) { 1088dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu return BAD_VALUE; 1089dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu } 1090dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu for (size_t i = 0; i < expectSize; ++i) { 1091dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu event[1].additional_info.data_float[i] = floats[i]; 1092dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu } 1093dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu } else { 1094dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu if (ints.size() != expectSize) { 1095dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu return BAD_VALUE; 1096dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu } 1097dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu for (size_t i = 0; i < expectSize; ++i) { 1098dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu event[1].additional_info.data_int32[i] = ints[i]; 1099dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu } 1100dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu } 1101dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu 1102dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu SensorDevice& dev(SensorDevice::getInstance()); 1103dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu for (sensors_event_t* i = event; i < event + 3; i++) { 1104dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu int ret = dev.injectSensorData(i); 1105dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu if (ret != NO_ERROR) { 1106dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu return ret; 1107dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu } 1108dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu } 1109dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu return NO_ERROR; 1110dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu} 1111dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu 1112a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatus_t SensorService::resetToNormalMode() { 1113a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella Mutex::Autolock _l(mLock); 1114a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella return resetToNormalModeLocked(); 1115a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella} 1116a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella 1117a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatus_t SensorService::resetToNormalModeLocked() { 1118a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella SensorDevice& dev(SensorDevice::getInstance()); 1119a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella status_t err = dev.setMode(NORMAL); 1120bfac17eed90d410de51413ef2484f79fb0e241e2Aniroop Mathur if (err == NO_ERROR) { 1121bfac17eed90d410de51413ef2484f79fb0e241e2Aniroop Mathur mCurrentOperatingMode = NORMAL; 1122bfac17eed90d410de51413ef2484f79fb0e241e2Aniroop Mathur dev.enableAllSensors(); 1123bfac17eed90d410de51413ef2484f79fb0e241e2Aniroop Mathur } 1124a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella return err; 1125a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella} 1126a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella 112747e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xuvoid SensorService::cleanupConnection(SensorEventConnection* c) { 1128fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian Mutex::Autolock _l(mLock); 1129db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian const wp<SensorEventConnection> connection(c); 11307c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian size_t size = mActiveSensors.size(); 1131db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn ALOGD_IF(DEBUG_CONNECTIONS, "%zu active sensors", size); 11327c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian for (size_t i=0 ; i<size ; ) { 1133db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian int handle = mActiveSensors.keyAt(i); 1134db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian if (c->hasSensor(handle)) { 1135db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn ALOGD_IF(DEBUG_CONNECTIONS, "%zu: disabling handle=0x%08x", i, handle); 1136755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 1137755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (sensor != nullptr) { 1138db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian sensor->activate(c, false); 1139755c451c7861a029e26e5f16e319b629169e656dPeng Xu } else { 1140755c451c7861a029e26e5f16e319b629169e656dPeng Xu ALOGE("sensor interface of handle=0x%08x is null!", handle); 1141f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 11428a96955c8e14db40b16164236830fc9506a00872Aravind Akella c->removeSensor(handle); 1143db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian } 1144db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian SensorRecord* rec = mActiveSensors.valueAt(i); 1145db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn ALOGE_IF(!rec, "mActiveSensors[%zu] is null (handle=0x%08x)!", i, handle); 1146a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block ALOGD_IF(DEBUG_CONNECTIONS, 1147db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn "removing connection %p for sensor[%zu].handle=0x%08x", 1148a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian c, i, handle); 1149a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian 1150db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian if (rec && rec->removeConnection(connection)) { 1151a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block ALOGD_IF(DEBUG_CONNECTIONS, "... and it was the last connection"); 11527c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian mActiveSensors.removeItemsAt(i, 1); 1153755c451c7861a029e26e5f16e319b629169e656dPeng Xu mActiveVirtualSensors.erase(handle); 11547c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian delete rec; 11557c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian size--; 11567c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian } else { 11577c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian i++; 1158fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 1159fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 11608a96955c8e14db40b16164236830fc9506a00872Aravind Akella c->updateLooperRegistration(mLooper); 11617c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian mActiveConnections.remove(connection); 1162787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian BatteryService::cleanup(c->getUid()); 11639a844cf78f09953145200b4074d47589257a408cAravind Akella if (c->needsWakeLock()) { 11649a844cf78f09953145200b4074d47589257a408cAravind Akella checkWakeLockStateLocked(); 11659a844cf78f09953145200b4074d47589257a408cAravind Akella } 11664f707f8b3da68d3055db895da9ae5216cc4f483aPeng Xu 11674f707f8b3da68d3055db895da9ae5216cc4f483aPeng Xu SensorDevice& dev(SensorDevice::getInstance()); 11684f707f8b3da68d3055db895da9ae5216cc4f483aPeng Xu dev.notifyConnectionDestroyed(c); 1169fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 1170fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 1171e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xuvoid SensorService::cleanupConnection(SensorDirectConnection* c) { 1172e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu Mutex::Autolock _l(mLock); 1173e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 1174e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu SensorDevice& dev(SensorDevice::getInstance()); 1175e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu dev.unregisterDirectChannel(c->getHalChannelHandle()); 1176e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu mDirectConnections.remove(c); 1177e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu} 1178e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 1179755c451c7861a029e26e5f16e319b629169e656dPeng Xusp<SensorInterface> SensorService::getSensorInterfaceFromHandle(int handle) const { 11800cc8f809924706c7d683da30605f432635dd5bb6Peng Xu return mSensors.getInterface(handle); 118147e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu} 118247e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu 1183fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::enable(const sp<SensorEventConnection>& connection, 1184b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags, 118547e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu const String16& opPackageName) { 118650df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian if (mInitCheck != NO_ERROR) 118750df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian return mInitCheck; 118850df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian 1189755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 1190755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (sensor == nullptr || 1191755c451c7861a029e26e5f16e319b629169e656dPeng Xu !canAccessSensor(sensor->getSensor(), "Tried enabling", opPackageName)) { 1192700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return BAD_VALUE; 1193700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } 1194700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 1195ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian Mutex::Autolock _l(mLock); 1196e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu if (mCurrentOperatingMode != NORMAL 1197841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella && !isWhiteListedPackage(connection->getPackageName())) { 11984949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella return INVALID_OPERATION; 11994949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella } 12004949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella 12014342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh SensorRecord* rec = mActiveSensors.valueFor(handle); 12024342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (rec == 0) { 12034342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh rec = new SensorRecord(connection); 12044342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh mActiveSensors.add(handle, rec); 12054342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (sensor->isVirtual()) { 1206755c451c7861a029e26e5f16e319b629169e656dPeng Xu mActiveVirtualSensors.emplace(handle); 12073560fb24b668675627934356f210d84d19bf4e56Mathias Agopian } 12084342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } else { 12094342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (rec->addConnection(connection)) { 12109a844cf78f09953145200b4074d47589257a408cAravind Akella // this sensor is already activated, but we are adding a connection that uses it. 12119a844cf78f09953145200b4074d47589257a408cAravind Akella // Immediately send down the last known value of the requested sensor if it's not a 12124342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // "continuous" sensor. 12130e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ON_CHANGE) { 12149a844cf78f09953145200b4074d47589257a408cAravind Akella // NOTE: The wake_up flag of this event may get set to 12159a844cf78f09953145200b4074d47589257a408cAravind Akella // WAKE_UP_SENSOR_EVENT_NEEDS_ACK if this is a wake_up event. 12166a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu 12176a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu auto logger = mRecentEvent.find(handle); 12186a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu if (logger != mRecentEvent.end()) { 1219444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella sensors_event_t event; 1220444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // It is unlikely that this buffer is empty as the sensor is already active. 1221444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // One possible corner case may be two applications activating an on-change 1222444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella // sensor at the same time. 12236a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu if(logger->second->populateLastEvent(&event)) { 1224444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella event.sensor = handle; 1225444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (event.version == sizeof(sensors_event_t)) { 1226444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (isWakeUpSensorEvent(event) && !mWakeLockAcquired) { 1227444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella setWakeLockAcquiredLocked(true); 1228444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 1229444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella connection->sendEvents(&event, 1, NULL); 1230444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella if (!connection->needsWakeLock() && mWakeLockAcquired) { 1231444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella checkWakeLockStateLocked(); 1232444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 1233444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella } 12349a844cf78f09953145200b4074d47589257a408cAravind Akella } 1235f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 12367c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian } 1237fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 1238fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 12394342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 12404342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (connection->addSensor(handle)) { 12414342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh BatteryService::enableSensor(connection->getUid(), handle); 12424342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // the sensor was added (which means it wasn't already there) 12434342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // so, see if this connection becomes active 12444342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (mActiveConnections.indexOf(connection) < 0) { 12454342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh mActiveConnections.add(connection); 12464342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 12474342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } else { 12484342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh ALOGW("sensor %08x already enabled in connection %p (ignoring)", 12494342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh handle, connection.get()); 12504342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 12514342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 1252d8a5ce39101f569f6bdab696ed02623e5aff7451Aniroop Mathur // Check maximum delay for the sensor. 1253663720b29f412756b8599897df9f8e32eb930be2Jim Kaye nsecs_t maxDelayNs = sensor->getSensor().getMaxDelay() * 1000LL; 1254d8a5ce39101f569f6bdab696ed02623e5aff7451Aniroop Mathur if (maxDelayNs > 0 && (samplingPeriodNs > maxDelayNs)) { 1255d8a5ce39101f569f6bdab696ed02623e5aff7451Aniroop Mathur samplingPeriodNs = maxDelayNs; 1256d8a5ce39101f569f6bdab696ed02623e5aff7451Aniroop Mathur } 1257d8a5ce39101f569f6bdab696ed02623e5aff7451Aniroop Mathur 1258724d91d778e71c8186399f4955de14b54812b3edAravind Akella nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs(); 1259724d91d778e71c8186399f4955de14b54812b3edAravind Akella if (samplingPeriodNs < minDelayNs) { 1260724d91d778e71c8186399f4955de14b54812b3edAravind Akella samplingPeriodNs = minDelayNs; 1261724d91d778e71c8186399f4955de14b54812b3edAravind Akella } 1262724d91d778e71c8186399f4955de14b54812b3edAravind Akella 12636c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d" 12646c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella "rate=%" PRId64 " timeout== %" PRId64"", 1265724d91d778e71c8186399f4955de14b54812b3edAravind Akella handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs); 1266724d91d778e71c8186399f4955de14b54812b3edAravind Akella 12674949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella status_t err = sensor->batch(connection.get(), handle, 0, samplingPeriodNs, 1268724d91d778e71c8186399f4955de14b54812b3edAravind Akella maxBatchReportLatencyNs); 12696c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 127020483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // Call flush() before calling activate() on the sensor. Wait for a first 127120483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // flush complete event before sending events on this connection. Ignore 127220483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // one-shot sensors which don't support flush(). Ignore on-change sensors 127320483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // to maintain the on-change logic (any on-change events except the initial 127420483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // one should be trigger by a change in value). Also if this sensor isn't 127520483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu // already active, don't call flush(). 127620483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu if (err == NO_ERROR && 12772576cb63b3fe1592f54816625036566b9eb0793aPeng Xu sensor->getSensor().getReportingMode() == AREPORTING_MODE_CONTINUOUS && 12785466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella rec->getNumConnections() > 1) { 12795466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella connection->setFirstFlushPending(handle, true); 12804c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella status_t err_flush = sensor->flush(connection.get(), handle); 12815466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // Flush may return error if the underlying h/w sensor uses an older HAL. 12826c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella if (err_flush == NO_ERROR) { 12836c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella rec->addPendingFlushConnection(connection.get()); 12845466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella } else { 12855466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella connection->setFirstFlushPending(handle, false); 12864c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 12874c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 1288724d91d778e71c8186399f4955de14b54812b3edAravind Akella 1289724d91d778e71c8186399f4955de14b54812b3edAravind Akella if (err == NO_ERROR) { 1290724d91d778e71c8186399f4955de14b54812b3edAravind Akella ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle); 1291724d91d778e71c8186399f4955de14b54812b3edAravind Akella err = sensor->activate(connection.get(), true); 1292724d91d778e71c8186399f4955de14b54812b3edAravind Akella } 1293724d91d778e71c8186399f4955de14b54812b3edAravind Akella 12948a96955c8e14db40b16164236830fc9506a00872Aravind Akella if (err == NO_ERROR) { 12958a96955c8e14db40b16164236830fc9506a00872Aravind Akella connection->updateLooperRegistration(mLooper); 129651224681c9a80ff714d40c26d8f465fb1bae17e2Peng Xu 129751224681c9a80ff714d40c26d8f465fb1bae17e2Peng Xu mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex) = 129851224681c9a80ff714d40c26d8f465fb1bae17e2Peng Xu SensorRegistrationInfo(handle, connection->getPackageName(), 129951224681c9a80ff714d40c26d8f465fb1bae17e2Peng Xu samplingPeriodNs, maxBatchReportLatencyNs, true); 130018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mNextSensorRegIndex = (mNextSensorRegIndex + 1) % SENSOR_REGISTRATIONS_BUF_SIZE; 130156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 130256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 13034342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (err != NO_ERROR) { 1304724d91d778e71c8186399f4955de14b54812b3edAravind Akella // batch/activate has failed, reset our state. 1305ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian cleanupWithoutDisableLocked(connection, handle); 13064342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 1307fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return err; 1308fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 1309fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 131047e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xustatus_t SensorService::disable(const sp<SensorEventConnection>& connection, int handle) { 131150df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian if (mInitCheck != NO_ERROR) 131250df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian return mInitCheck; 131350df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian 1314ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian Mutex::Autolock _l(mLock); 1315ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian status_t err = cleanupWithoutDisableLocked(connection, handle); 13164342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (err == NO_ERROR) { 1317755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 1318755c451c7861a029e26e5f16e319b629169e656dPeng Xu err = sensor != nullptr ? sensor->activate(connection.get(), false) : status_t(BAD_VALUE); 131918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella 132018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella } 132118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella if (err == NO_ERROR) { 132251224681c9a80ff714d40c26d8f465fb1bae17e2Peng Xu mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex) = 132351224681c9a80ff714d40c26d8f465fb1bae17e2Peng Xu SensorRegistrationInfo(handle, connection->getPackageName(), 0, 0, false); 132418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella mNextSensorRegIndex = (mNextSensorRegIndex + 1) % SENSOR_REGISTRATIONS_BUF_SIZE; 13254342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 13264342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh return err; 13274342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh} 13284342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 1329ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisable( 1330ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian const sp<SensorEventConnection>& connection, int handle) { 1331fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian Mutex::Autolock _l(mLock); 1332ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian return cleanupWithoutDisableLocked(connection, handle); 1333ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian} 1334ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian 1335ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisableLocked( 1336ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian const sp<SensorEventConnection>& connection, int handle) { 1337fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian SensorRecord* rec = mActiveSensors.valueFor(handle); 1338fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian if (rec) { 1339fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian // see if this connection becomes inactive 1340787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian if (connection->removeSensor(handle)) { 1341787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian BatteryService::disableSensor(connection->getUid(), handle); 1342787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian } 1343fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian if (connection->hasAnySensor() == false) { 13448a96955c8e14db40b16164236830fc9506a00872Aravind Akella connection->updateLooperRegistration(mLooper); 1345fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian mActiveConnections.remove(connection); 1346fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 1347fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian // see if this sensor becomes inactive 1348fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian if (rec->removeConnection(connection)) { 1349fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian mActiveSensors.removeItem(handle); 1350755c451c7861a029e26e5f16e319b629169e656dPeng Xu mActiveVirtualSensors.erase(handle); 1351fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian delete rec; 1352fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 13534342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh return NO_ERROR; 13547c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian } 13554342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh return BAD_VALUE; 1356fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 1357fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 13587c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianstatus_t SensorService::setEventRate(const sp<SensorEventConnection>& connection, 135947e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu int handle, nsecs_t ns, const String16& opPackageName) { 136050df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian if (mInitCheck != NO_ERROR) 136150df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian return mInitCheck; 136250df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian 1363755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 1364755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (sensor == nullptr || 1365755c451c7861a029e26e5f16e319b629169e656dPeng Xu !canAccessSensor(sensor->getSensor(), "Tried configuring", opPackageName)) { 1366700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return BAD_VALUE; 1367700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } 1368700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 13691cd700015318727d6d42236ab6274f1949fb08baMathias Agopian if (ns < 0) 13701cd700015318727d6d42236ab6274f1949fb08baMathias Agopian return BAD_VALUE; 13711cd700015318727d6d42236ab6274f1949fb08baMathias Agopian 137262569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs(); 137362569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian if (ns < minDelayNs) { 137462569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian ns = minDelayNs; 1375ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian } 1376ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian 1377f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian return sensor->setDelay(connection.get(), handle, ns); 1378fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 1379fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 1380b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslavstatus_t SensorService::flushSensor(const sp<SensorEventConnection>& connection, 1381b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav const String16& opPackageName) { 1382700180487ffec09d9df1657b018a7caadac24b75Aravind Akella if (mInitCheck != NO_ERROR) return mInitCheck; 13839e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella SensorDevice& dev(SensorDevice::getInstance()); 13849e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella const int halVersion = dev.getHalDeviceVersion(); 13859e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella status_t err(NO_ERROR); 13869e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella Mutex::Autolock _l(mLock); 13879e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // Loop through all sensors for this connection and call flush on each of them. 13889e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella for (size_t i = 0; i < connection->mSensorInfo.size(); ++i) { 13899e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella const int handle = connection->mSensorInfo.keyAt(i); 1390755c451c7861a029e26e5f16e319b629169e656dPeng Xu sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle); 1391755c451c7861a029e26e5f16e319b629169e656dPeng Xu if (sensor == nullptr) { 1392755c451c7861a029e26e5f16e319b629169e656dPeng Xu continue; 1393755c451c7861a029e26e5f16e319b629169e656dPeng Xu } 13949e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) { 13959e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella ALOGE("flush called on a one-shot sensor"); 13969e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella err = INVALID_OPERATION; 13979e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella continue; 13989e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } 13998493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella if (halVersion <= SENSORS_DEVICE_API_VERSION_1_0 || isVirtualSensor(handle)) { 14009e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // For older devices just increment pending flush count which will send a trivial 14019e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // flush complete event. 14028a96955c8e14db40b16164236830fc9506a00872Aravind Akella connection->incrementPendingFlushCount(handle); 14039e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } else { 1404b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (!canAccessSensor(sensor->getSensor(), "Tried flushing", opPackageName)) { 1405b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav err = INVALID_OPERATION; 1406b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav continue; 1407b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav } 14089e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella status_t err_flush = sensor->flush(connection.get(), handle); 14099e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella if (err_flush == NO_ERROR) { 14109e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella SensorRecord* rec = mActiveSensors.valueFor(handle); 14119e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella if (rec != NULL) rec->addPendingFlushConnection(connection); 14129e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } 14139e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella err = (err_flush != NO_ERROR) ? err_flush : err; 14149e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } 14156c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } 14169e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella return err; 1417700180487ffec09d9df1657b018a7caadac24b75Aravind Akella} 1418700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 1419b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslavbool SensorService::canAccessSensor(const Sensor& sensor, const char* operation, 1420b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav const String16& opPackageName) { 1421b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav const String8& requiredPermission = sensor.getRequiredPermission(); 1422700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 1423b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (requiredPermission.length() <= 0) { 1424700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return true; 1425b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav } 1426b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav 1427b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav bool hasPermission = false; 1428b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav 1429b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav // Runtime permissions can't use the cache as they may change. 1430b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (sensor.isRequiredPermissionRuntime()) { 1431b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav hasPermission = checkPermission(String16(requiredPermission), 1432b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav IPCThreadState::self()->getCallingPid(), IPCThreadState::self()->getCallingUid()); 1433700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } else { 1434b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav hasPermission = PermissionCache::checkCallingPermission(String16(requiredPermission)); 1435b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav } 1436b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav 1437b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (!hasPermission) { 1438b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav ALOGE("%s a sensor (%s) without holding its required permission: %s", 1439b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav operation, sensor.getName().string(), sensor.getRequiredPermission().string()); 1440700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return false; 1441700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } 1442b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav 1443b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav const int32_t opCode = sensor.getRequiredAppOp(); 1444b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (opCode >= 0) { 1445b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav AppOpsManager appOps; 1446b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav if (appOps.noteOp(opCode, IPCThreadState::self()->getCallingUid(), opPackageName) 1447b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav != AppOpsManager::MODE_ALLOWED) { 1448d4036b6b7f9609fe09efabdbfbb8c8f9428f76f7Andreas Gampe ALOGE("%s a sensor (%s) without enabled required app op: %d", 1449b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav operation, sensor.getName().string(), opCode); 1450b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav return false; 1451b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav } 1452b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav } 1453b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav 1454b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav return true; 1455700180487ffec09d9df1657b018a7caadac24b75Aravind Akella} 1456700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 14579a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockState() { 14589a844cf78f09953145200b4074d47589257a408cAravind Akella Mutex::Autolock _l(mLock); 14599a844cf78f09953145200b4074d47589257a408cAravind Akella checkWakeLockStateLocked(); 14609a844cf78f09953145200b4074d47589257a408cAravind Akella} 14619a844cf78f09953145200b4074d47589257a408cAravind Akella 14629a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockStateLocked() { 14639a844cf78f09953145200b4074d47589257a408cAravind Akella if (!mWakeLockAcquired) { 14649a844cf78f09953145200b4074d47589257a408cAravind Akella return; 14659a844cf78f09953145200b4074d47589257a408cAravind Akella } 14669a844cf78f09953145200b4074d47589257a408cAravind Akella bool releaseLock = true; 14679a844cf78f09953145200b4074d47589257a408cAravind Akella for (size_t i=0 ; i<mActiveConnections.size() ; i++) { 14689a844cf78f09953145200b4074d47589257a408cAravind Akella sp<SensorEventConnection> connection(mActiveConnections[i].promote()); 14699a844cf78f09953145200b4074d47589257a408cAravind Akella if (connection != 0) { 14709a844cf78f09953145200b4074d47589257a408cAravind Akella if (connection->needsWakeLock()) { 14719a844cf78f09953145200b4074d47589257a408cAravind Akella releaseLock = false; 14729a844cf78f09953145200b4074d47589257a408cAravind Akella break; 14739a844cf78f09953145200b4074d47589257a408cAravind Akella } 14749a844cf78f09953145200b4074d47589257a408cAravind Akella } 14759a844cf78f09953145200b4074d47589257a408cAravind Akella } 14769a844cf78f09953145200b4074d47589257a408cAravind Akella if (releaseLock) { 1477b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella setWakeLockAcquiredLocked(false); 1478b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 1479b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella} 1480b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella 1481b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::sendEventsFromCache(const sp<SensorEventConnection>& connection) { 1482b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella Mutex::Autolock _l(mLock); 1483b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella connection->writeToSocketFromCache(); 1484b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (connection->needsWakeLock()) { 1485b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella setWakeLockAcquiredLocked(true); 1486b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 1487b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella} 1488b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella 1489b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::populateActiveConnections( 1490b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella SortedVector< sp<SensorEventConnection> >* activeConnections) { 1491b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella Mutex::Autolock _l(mLock); 1492b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella for (size_t i=0 ; i < mActiveConnections.size(); ++i) { 1493b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella sp<SensorEventConnection> connection(mActiveConnections[i].promote()); 1494b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella if (connection != 0) { 1495b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella activeConnections->add(connection); 1496b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella } 14979a844cf78f09953145200b4074d47589257a408cAravind Akella } 14989a844cf78f09953145200b4074d47589257a408cAravind Akella} 14996c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 15004949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akellabool SensorService::isWhiteListedPackage(const String8& packageName) { 1501841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella return (packageName.contains(mWhiteListedPackage.string())); 15024949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella} 15034949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella 1504e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xubool SensorService::isOperationRestricted(const String16& opPackageName) { 1505e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu Mutex::Autolock _l(mLock); 1506e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu if (mCurrentOperatingMode != RESTRICTED) { 1507e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu String8 package(opPackageName); 1508e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu return !isWhiteListedPackage(package); 1509e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu } 1510e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu return false; 1511e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu} 1512e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu 1513fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}; // namespace android 1514