SensorService.cpp revision 9e3adfcebf28c5c76085108dffe98c74df56857d
1fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian/* 2fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * Copyright (C) 2010 The Android Open Source Project 3fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * 4fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 5fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * you may not use this file except in compliance with the License. 6fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * You may obtain a copy of the License at 7fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * 8fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 9fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * 10fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * Unless required by applicable law or agreed to in writing, software 11fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 12fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * See the License for the specific language governing permissions and 14fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * limitations under the License. 15fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian */ 16fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 1792dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn#include <inttypes.h> 18f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include <math.h> 1992dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn#include <stdint.h> 20fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <sys/types.h> 2156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#include <sys/socket.h> 22fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 233301542828febc768e1df42892cfac4992c35474Mathias Agopian#include <cutils/properties.h> 243301542828febc768e1df42892cfac4992c35474Mathias Agopian 25fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <utils/SortedVector.h> 26fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <utils/KeyedVector.h> 27fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <utils/threads.h> 28fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <utils/Atomic.h> 29fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <utils/Errors.h> 30fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <utils/RefBase.h> 31451beee076cac09f817abae78a990dea108a9482Mathias Agopian#include <utils/Singleton.h> 32c4a930d1d5a432a1f302763ac55460d6e83fe7e0Mathias Agopian#include <utils/String16.h> 33fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 34fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <binder/BinderService.h> 35451beee076cac09f817abae78a990dea108a9482Mathias Agopian#include <binder/IServiceManager.h> 361cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian#include <binder/PermissionCache.h> 37fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 38fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <gui/ISensorServer.h> 39fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <gui/ISensorEventConnection.h> 40907103bf186cfdd2ed9eb3b6c36de53ade7b16f6Mathias Agopian#include <gui/SensorEventQueue.h> 41fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 42fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <hardware/sensors.h> 434342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh#include <hardware_legacy/power.h> 44fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 45787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian#include "BatteryService.h" 46984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "CorrectedGyroSensor.h" 47f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "GravitySensor.h" 48f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "LinearAccelerationSensor.h" 49984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "OrientationSensor.h" 50f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "RotationVectorSensor.h" 51984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "SensorFusion.h" 52984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "SensorService.h" 53fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 54fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopiannamespace android { 55fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// --------------------------------------------------------------------------- 56fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 573301542828febc768e1df42892cfac4992c35474Mathias Agopian/* 583301542828febc768e1df42892cfac4992c35474Mathias Agopian * Notes: 593301542828febc768e1df42892cfac4992c35474Mathias Agopian * 603301542828febc768e1df42892cfac4992c35474Mathias Agopian * - what about a gyro-corrected magnetic-field sensor? 613301542828febc768e1df42892cfac4992c35474Mathias Agopian * - run mag sensor from time to time to force calibration 623301542828febc768e1df42892cfac4992c35474Mathias Agopian * - gravity sensor length is wrong (=> drift in linear-acc sensor) 633301542828febc768e1df42892cfac4992c35474Mathias Agopian * 643301542828febc768e1df42892cfac4992c35474Mathias Agopian */ 653301542828febc768e1df42892cfac4992c35474Mathias Agopian 664342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganeshconst char* SensorService::WAKE_LOCK_NAME = "SensorService"; 674342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 68fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorService() 691cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian : mInitCheck(NO_INIT) 70fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 71fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 72fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 73fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianvoid SensorService::onFirstRef() 74fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 75a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block ALOGD("nuSensorService starting..."); 7650df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian 77f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian SensorDevice& dev(SensorDevice::getInstance()); 78fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 79f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian if (dev.initCheck() == NO_ERROR) { 80f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sensor_t const* list; 817b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian ssize_t count = dev.getSensorList(&list); 827b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian if (count > 0) { 837b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian ssize_t orientationIndex = -1; 847b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian bool hasGyro = false; 857b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian uint32_t virtualSensorsNeeds = 867b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian (1<<SENSOR_TYPE_GRAVITY) | 877b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian (1<<SENSOR_TYPE_LINEAR_ACCELERATION) | 887b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian (1<<SENSOR_TYPE_ROTATION_VECTOR); 897b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian 907b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian mLastEventSeen.setCapacity(count); 917b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian for (ssize_t i=0 ; i<count ; i++) { 927b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian registerSensor( new HardwareSensor(list[i]) ); 937b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian switch (list[i].type) { 947b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian case SENSOR_TYPE_ORIENTATION: 957b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian orientationIndex = i; 967b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian break; 977b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian case SENSOR_TYPE_GYROSCOPE: 980319306670b0344da99efa606b6f172dde575a39Mathias Agopian case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED: 997b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian hasGyro = true; 1007b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian break; 1017b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian case SENSOR_TYPE_GRAVITY: 1027b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian case SENSOR_TYPE_LINEAR_ACCELERATION: 1037b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian case SENSOR_TYPE_ROTATION_VECTOR: 1047b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian virtualSensorsNeeds &= ~(1<<list[i].type); 1057b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian break; 1067b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian } 10750df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian } 108fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 1097b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian // it's safe to instantiate the SensorFusion object here 1107b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian // (it wants to be instantiated after h/w sensors have been 1117b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian // registered) 1127b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian const SensorFusion& fusion(SensorFusion::getInstance()); 1137b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian 1140319306670b0344da99efa606b6f172dde575a39Mathias Agopian // build the sensor list returned to users 1150319306670b0344da99efa606b6f172dde575a39Mathias Agopian mUserSensorList = mSensorList; 1160319306670b0344da99efa606b6f172dde575a39Mathias Agopian 1177b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian if (hasGyro) { 1180319306670b0344da99efa606b6f172dde575a39Mathias Agopian Sensor aSensor; 1197b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian 1200319306670b0344da99efa606b6f172dde575a39Mathias Agopian // Add Android virtual sensors if they're not already 1210319306670b0344da99efa606b6f172dde575a39Mathias Agopian // available in the HAL 1227b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian 1230319306670b0344da99efa606b6f172dde575a39Mathias Agopian aSensor = registerVirtualSensor( new RotationVectorSensor() ); 1240319306670b0344da99efa606b6f172dde575a39Mathias Agopian if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) { 1250319306670b0344da99efa606b6f172dde575a39Mathias Agopian mUserSensorList.add(aSensor); 1260319306670b0344da99efa606b6f172dde575a39Mathias Agopian } 127f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 1280319306670b0344da99efa606b6f172dde575a39Mathias Agopian aSensor = registerVirtualSensor( new GravitySensor(list, count) ); 1290319306670b0344da99efa606b6f172dde575a39Mathias Agopian if (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) { 1300319306670b0344da99efa606b6f172dde575a39Mathias Agopian mUserSensorList.add(aSensor); 1310319306670b0344da99efa606b6f172dde575a39Mathias Agopian } 13233264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian 1330319306670b0344da99efa606b6f172dde575a39Mathias Agopian aSensor = registerVirtualSensor( new LinearAccelerationSensor(list, count) ); 1340319306670b0344da99efa606b6f172dde575a39Mathias Agopian if (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) { 1350319306670b0344da99efa606b6f172dde575a39Mathias Agopian mUserSensorList.add(aSensor); 1360319306670b0344da99efa606b6f172dde575a39Mathias Agopian } 13733264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian 1380319306670b0344da99efa606b6f172dde575a39Mathias Agopian aSensor = registerVirtualSensor( new OrientationSensor() ); 1390319306670b0344da99efa606b6f172dde575a39Mathias Agopian if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) { 1400319306670b0344da99efa606b6f172dde575a39Mathias Agopian // if we are doing our own rotation-vector, also add 1410319306670b0344da99efa606b6f172dde575a39Mathias Agopian // the orientation sensor and remove the HAL provided one. 1420319306670b0344da99efa606b6f172dde575a39Mathias Agopian mUserSensorList.replaceAt(aSensor, orientationIndex); 1437b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian } 1440319306670b0344da99efa606b6f172dde575a39Mathias Agopian 1450319306670b0344da99efa606b6f172dde575a39Mathias Agopian // virtual debugging sensors are not added to mUserSensorList 1460319306670b0344da99efa606b6f172dde575a39Mathias Agopian registerVirtualSensor( new CorrectedGyroSensor(list, count) ); 1470319306670b0344da99efa606b6f172dde575a39Mathias Agopian registerVirtualSensor( new GyroDriftSensor() ); 148010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian } 149010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian 15033264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian // debugging sensor list 1510319306670b0344da99efa606b6f172dde575a39Mathias Agopian mUserSensorListDebug = mSensorList; 15233264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian 1535466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // Check if the device really supports batching by looking at the FIFO event 1545466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // counts for each sensor. 1555466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella bool batchingSupported = false; 1565466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella for (int i = 0; i < mSensorList.size(); ++i) { 1575466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella if (mSensorList[i].getFifoMaxEventCount() > 0) { 1585466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella batchingSupported = true; 1595466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella break; 1605466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella } 1615466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella } 1625466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella 1635466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella if (batchingSupported) { 1645466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // Increase socket buffer size to a max of 100 KB for batching capabilities. 1655466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella mSocketBufferSize = MAX_SOCKET_BUFFER_SIZE_BATCHED; 1665466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella } else { 1675466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella mSocketBufferSize = SOCKET_BUFFER_SIZE_NON_BATCHED; 1685466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella } 1695466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella 1705466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // Compare the socketBufferSize value against the system limits and limit 1715466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // it to maxSystemSocketBufferSize if necessary. 1724c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella FILE *fp = fopen("/proc/sys/net/core/wmem_max", "r"); 1734c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella char line[128]; 1744c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella if (fp != NULL && fgets(line, sizeof(line), fp) != NULL) { 1754c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella line[sizeof(line) - 1] = '\0'; 1765466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella size_t maxSystemSocketBufferSize; 1775466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella sscanf(line, "%zu", &maxSystemSocketBufferSize); 1785466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella if (mSocketBufferSize > maxSystemSocketBufferSize) { 1795466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella mSocketBufferSize = maxSystemSocketBufferSize; 1804c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 1814c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 1824c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella if (fp) { 1834c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella fclose(fp); 1844c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 1854c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella 1869a844cf78f09953145200b4074d47589257a408cAravind Akella mWakeLockAcquired = false; 1877b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian run("SensorService", PRIORITY_URGENT_DISPLAY); 18856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella mLooper = new Looper(false); 1897b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian mInitCheck = NO_ERROR; 1907b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian } 191fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 192fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 193fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 1940319306670b0344da99efa606b6f172dde575a39Mathias AgopianSensor SensorService::registerSensor(SensorInterface* s) 195f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{ 196f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sensors_event_t event; 197f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian memset(&event, 0, sizeof(event)); 198f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 199f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian const Sensor sensor(s->getSensor()); 200f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian // add to the sensor list (returned to clients) 201f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian mSensorList.add(sensor); 202f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian // add to our handle->SensorInterface mapping 203f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian mSensorMap.add(sensor.getHandle(), s); 204f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian // create an entry in the mLastEventSeen array 205f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian mLastEventSeen.add(sensor.getHandle(), event); 2060319306670b0344da99efa606b6f172dde575a39Mathias Agopian 2070319306670b0344da99efa606b6f172dde575a39Mathias Agopian return sensor; 208f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian} 209f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 2100319306670b0344da99efa606b6f172dde575a39Mathias AgopianSensor SensorService::registerVirtualSensor(SensorInterface* s) 211f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{ 2120319306670b0344da99efa606b6f172dde575a39Mathias Agopian Sensor sensor = registerSensor(s); 213f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian mVirtualSensorList.add( s ); 2140319306670b0344da99efa606b6f172dde575a39Mathias Agopian return sensor; 215f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian} 216f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 217fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::~SensorService() 218fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 219f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian for (size_t i=0 ; i<mSensorMap.size() ; i++) 220f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian delete mSensorMap.valueAt(i); 221fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 222fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 2231cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopianstatic const String16 sDump("android.permission.DUMP"); 2241cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian 22592dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzynstatus_t SensorService::dump(int fd, const Vector<String16>& /*args*/) 226fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 227fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian String8 result; 2281cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian if (!PermissionCache::checkCallingPermission(sDump)) { 229ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian result.appendFormat("Permission Denial: " 230700180487ffec09d9df1657b018a7caadac24b75Aravind Akella "can't dump SensorService from pid=%d, uid=%d\n", 231fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian IPCThreadState::self()->getCallingPid(), 232fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian IPCThreadState::self()->getCallingUid()); 233fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } else { 234fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian Mutex::Autolock _l(mLock); 235ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian result.append("Sensor List:\n"); 2363560fb24b668675627934356f210d84d19bf4e56Mathias Agopian for (size_t i=0 ; i<mSensorList.size() ; i++) { 2373560fb24b668675627934356f210d84d19bf4e56Mathias Agopian const Sensor& s(mSensorList[i]); 2383560fb24b668675627934356f210d84d19bf4e56Mathias Agopian const sensors_event_t& e(mLastEventSeen.valueFor(s.getHandle())); 239ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian result.appendFormat( 2406c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella "%-15s| %-10s| %-20s| 0x%08x | \"%s\" | type=%d |", 2413560fb24b668675627934356f210d84d19bf4e56Mathias Agopian s.getName().string(), 2423560fb24b668675627934356f210d84d19bf4e56Mathias Agopian s.getVendor().string(), 243700180487ffec09d9df1657b018a7caadac24b75Aravind Akella s.getStringType().string(), 244700180487ffec09d9df1657b018a7caadac24b75Aravind Akella s.getHandle(), 2456c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella s.getRequiredPermission().string(), 2466c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella s.getType()); 247ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian 2480e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella const int reportingMode = s.getReportingMode(); 2490e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella if (reportingMode == AREPORTING_MODE_CONTINUOUS) { 2506c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella result.append(" continuous | "); 2510e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella } else if (reportingMode == AREPORTING_MODE_ON_CHANGE) { 2526c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella result.append(" on-change | "); 2530e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella } else if (reportingMode == AREPORTING_MODE_ONE_SHOT) { 2546c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella result.append(" one-shot | "); 2550e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella } else { 2566c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella result.append(" special-trigger | "); 2576c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } 2586c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 2596c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella if (s.getMaxDelay() > 0) { 2606c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella result.appendFormat("minRate=%.2fHz | ", 1e6f / s.getMaxDelay()); 2616c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } else { 2626c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella result.appendFormat("maxDelay=%dus |", s.getMaxDelay()); 2630e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella } 2640e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella 265ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian if (s.getMinDelay() > 0) { 2666c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella result.appendFormat("maxRate=%.2fHz | ", 1e6f / s.getMinDelay()); 267ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian } else { 2686c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella result.appendFormat("minDelay=%dus |", s.getMinDelay()); 269ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian } 2700e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella 271724d91d778e71c8186399f4955de14b54812b3edAravind Akella if (s.getFifoMaxEventCount() > 0) { 272700180487ffec09d9df1657b018a7caadac24b75Aravind Akella result.appendFormat("FifoMax=%d events | ", 273700180487ffec09d9df1657b018a7caadac24b75Aravind Akella s.getFifoMaxEventCount()); 274724d91d778e71c8186399f4955de14b54812b3edAravind Akella } else { 2756c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella result.append("no batching | "); 2766c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } 2776c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 2786c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella if (s.isWakeUpSensor()) { 2796c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella result.appendFormat("wakeUp | "); 2806c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } else { 2816c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella result.appendFormat("non-wakeUp | "); 282724d91d778e71c8186399f4955de14b54812b3edAravind Akella } 283ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian 284ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian switch (s.getType()) { 285ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian case SENSOR_TYPE_ROTATION_VECTOR: 286ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR: 287ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian result.appendFormat( 2886c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella "last=<%5.1f,%5.1f,%5.1f,%5.1f,%5.1f, %" PRId64 ">\n", 2896c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella e.data[0], e.data[1], e.data[2], e.data[3], e.data[4], e.timestamp); 290ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian break; 291ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED: 292ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED: 293ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian result.appendFormat( 2946c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella "last=<%5.1f,%5.1f,%5.1f,%5.1f,%5.1f,%5.1f, %" PRId64 ">\n", 2956c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella e.data[0], e.data[1], e.data[2], e.data[3], e.data[4], e.data[5], 2966c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella e.timestamp); 297ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian break; 298ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian case SENSOR_TYPE_GAME_ROTATION_VECTOR: 299ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian result.appendFormat( 3006c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella "last=<%5.1f,%5.1f,%5.1f,%5.1f, %" PRId64 ">\n", 3016c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella e.data[0], e.data[1], e.data[2], e.data[3], e.timestamp); 302ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian break; 303ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian case SENSOR_TYPE_SIGNIFICANT_MOTION: 304ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian case SENSOR_TYPE_STEP_DETECTOR: 3056c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella result.appendFormat( "last=<%f %" PRId64 ">\n", e.data[0], e.timestamp); 306ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian break; 307ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian case SENSOR_TYPE_STEP_COUNTER: 3086c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella result.appendFormat( "last=<%" PRIu64 ", %" PRId64 ">\n", e.u64.step_counter, 3096c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella e.timestamp); 310ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian break; 311ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian default: 312ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian // default to 3 values 313ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian result.appendFormat( 3146c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella "last=<%5.1f,%5.1f,%5.1f, %" PRId64 ">\n", 3156c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella e.data[0], e.data[1], e.data[2], e.timestamp); 316ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian break; 317ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian } 3186c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella result.append("\n"); 3193560fb24b668675627934356f210d84d19bf4e56Mathias Agopian } 320ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian SensorFusion::getInstance().dump(result); 321ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian SensorDevice::getInstance().dump(result); 322ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian 323ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian result.append("Active sensors:\n"); 324fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian for (size_t i=0 ; i<mActiveSensors.size() ; i++) { 3255d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian int handle = mActiveSensors.keyAt(i); 32692dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn result.appendFormat("%s (handle=0x%08x, connections=%zu)\n", 3275d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian getSensorName(handle).string(), 3285d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian handle, 329fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian mActiveSensors.valueAt(i)->getNumConnections()); 330fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 3314c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella 3325466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella result.appendFormat("Socket Buffer size = %d events\n", 3336c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella mSocketBufferSize/sizeof(sensors_event_t)); 3349a844cf78f09953145200b4074d47589257a408cAravind Akella result.appendFormat("WakeLock Status: %s \n", mWakeLockAcquired ? "acquired" : "not held"); 33592dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn result.appendFormat("%zd active connections\n", mActiveConnections.size()); 3364c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella 3374c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella for (size_t i=0 ; i < mActiveConnections.size() ; i++) { 3384c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella sp<SensorEventConnection> connection(mActiveConnections[i].promote()); 3394c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella if (connection != 0) { 34092dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn result.appendFormat("Connection Number: %zu \n", i); 3414c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella connection->dump(result); 3424c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 3434c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 344fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 345fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian write(fd, result.string(), result.size()); 346fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return NO_ERROR; 347fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 348fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 3499a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::cleanupAutoDisabledSensorLocked(const sp<SensorEventConnection>& connection, 3504342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh sensors_event_t const* buffer, const int count) { 3514342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh for (int i=0 ; i<count ; i++) { 3524342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh int handle = buffer[i].sensor; 3530e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella if (connection->hasSensor(handle)) { 3540e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella SensorInterface* sensor = mSensorMap.valueFor(handle); 3550e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella // If this buffer has an event from a one_shot sensor and this connection is registered 3560e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella // for this particular one_shot sensor, try cleaning up the connection. 3570e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella if (sensor != NULL && 3580e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) { 3590e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella sensor->autoDisable(connection.get(), handle); 3609a844cf78f09953145200b4074d47589257a408cAravind Akella cleanupWithoutDisableLocked(connection, handle); 3614342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 3624342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 3634342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 3644342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh} 3654342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 366fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::threadLoop() 367fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 368a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block ALOGD("nuSensorService thread starting..."); 369fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 37090ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian // each virtual sensor could generate an event per "real" event, that's why we need 37190ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian // to size numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT. 37290ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian // in practice, this is too aggressive, but guaranteed to be enough. 37390ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT; 37490ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian const size_t numEventMax = minBufferSize / (1 + mVirtualSensorList.size()); 37590ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian 376d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian sensors_event_t buffer[minBufferSize]; 377d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian sensors_event_t scratch[minBufferSize]; 378f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian SensorDevice& device(SensorDevice::getInstance()); 379f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian const size_t vcount = mVirtualSensorList.size(); 380fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 38156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella SensorEventAckReceiver sender(this); 38256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella sender.run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY); 383f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian ssize_t count; 3844342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh const int halVersion = device.getHalDeviceVersion(); 385fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian do { 386f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian count = device.poll(buffer, numEventMax); 387fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian if (count<0) { 388f5a1230d322c14c42331d0a1536b50c87742973bSteve Block ALOGE("sensor poll failed (%s)", strerror(-count)); 389fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian break; 390fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 39156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 39256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // Reset sensors_event_t.flags to zero for all events in the buffer. 39356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella for (int i = 0; i < count; i++) { 39456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella buffer[i].flags = 0; 39556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 3969a844cf78f09953145200b4074d47589257a408cAravind Akella Mutex::Autolock _l(mLock); 3979a844cf78f09953145200b4074d47589257a408cAravind Akella // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The 3989a844cf78f09953145200b4074d47589257a408cAravind Akella // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock, 3999a844cf78f09953145200b4074d47589257a408cAravind Akella // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should 4009a844cf78f09953145200b4074d47589257a408cAravind Akella // not be interleaved with decrementing SensorEventConnection::mWakeLockRefCount and 4019a844cf78f09953145200b4074d47589257a408cAravind Akella // releasing the wakelock. 4029a844cf78f09953145200b4074d47589257a408cAravind Akella bool bufferHasWakeUpEvent = false; 4034342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh for (int i = 0; i < count; i++) { 4049a844cf78f09953145200b4074d47589257a408cAravind Akella if (isWakeUpSensorEvent(buffer[i])) { 4059a844cf78f09953145200b4074d47589257a408cAravind Akella bufferHasWakeUpEvent = true; 4069a844cf78f09953145200b4074d47589257a408cAravind Akella break; 4074342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 4084342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 4094342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 4109a844cf78f09953145200b4074d47589257a408cAravind Akella if (bufferHasWakeUpEvent && !mWakeLockAcquired) { 4119a844cf78f09953145200b4074d47589257a408cAravind Akella acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME); 4129a844cf78f09953145200b4074d47589257a408cAravind Akella mWakeLockAcquired = true; 4139a844cf78f09953145200b4074d47589257a408cAravind Akella ALOGD_IF(DEBUG_CONNECTIONS, "acquired wakelock %s", WAKE_LOCK_NAME); 4149a844cf78f09953145200b4074d47589257a408cAravind Akella } 4159a844cf78f09953145200b4074d47589257a408cAravind Akella recordLastValueLocked(buffer, count); 41694e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian 417f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian // handle virtual sensors 418f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian if (count && vcount) { 419984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian sensors_event_t const * const event = buffer; 4209a844cf78f09953145200b4074d47589257a408cAravind Akella const size_t activeVirtualSensorCount = mActiveVirtualSensors.size(); 421f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian if (activeVirtualSensorCount) { 422f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian size_t k = 0; 423984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian SensorFusion& fusion(SensorFusion::getInstance()); 424984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian if (fusion.isEnabled()) { 425984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t i=0 ; i<size_t(count) ; i++) { 426984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian fusion.process(event[i]); 427984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 428984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 429d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) { 430f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian for (size_t j=0 ; j<activeVirtualSensorCount ; j++) { 431d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian if (count + k >= minBufferSize) { 432d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian ALOGE("buffer too small to hold all events: " 433db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn "count=%zd, k=%zu, size=%zu", 434d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian count, k, minBufferSize); 435d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian break; 436d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian } 437f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sensors_event_t out; 4389a844cf78f09953145200b4074d47589257a408cAravind Akella SensorInterface* si = mActiveVirtualSensors.valueAt(j); 439d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian if (si->process(&out, event[i])) { 440f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian buffer[count + k] = out; 441f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian k++; 442f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 443f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 444f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 445f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian if (k) { 446f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian // record the last synthesized values 4479a844cf78f09953145200b4074d47589257a408cAravind Akella recordLastValueLocked(&buffer[count], k); 448f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian count += k; 449f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian // sort the buffer by time-stamps 450f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sortEventBuffer(buffer, count); 451f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 452f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 453f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 454f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 4554342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // handle backward compatibility for RotationVector sensor 4564342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) { 4574342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh for (int i = 0; i < count; i++) { 4587438fd1a0132bc6de101e2a5f75040a119b6f29bMathias Agopian if (buffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) { 4594342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // All the 4 components of the quaternion should be available 4604342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // No heading accuracy. Set it to -1 4614342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh buffer[i].data[4] = -1; 4624342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 4634342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 4644342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 4654342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 4669a844cf78f09953145200b4074d47589257a408cAravind Akella // Send our events to clients. Check the state of wake lock for each client and release the 4679a844cf78f09953145200b4074d47589257a408cAravind Akella // lock if none of the clients need it. 4689a844cf78f09953145200b4074d47589257a408cAravind Akella bool needsWakeLock = false; 4699a844cf78f09953145200b4074d47589257a408cAravind Akella for (size_t i=0 ; i < mActiveConnections.size(); i++) { 4709a844cf78f09953145200b4074d47589257a408cAravind Akella sp<SensorEventConnection> connection(mActiveConnections[i].promote()); 471f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian if (connection != 0) { 472f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian connection->sendEvents(buffer, count, scratch); 4739a844cf78f09953145200b4074d47589257a408cAravind Akella needsWakeLock |= connection->needsWakeLock(); 4744342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // Some sensors need to be auto disabled after the trigger 4759a844cf78f09953145200b4074d47589257a408cAravind Akella cleanupAutoDisabledSensorLocked(connection, buffer, count); 476fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 477fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 4784342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 4799a844cf78f09953145200b4074d47589257a408cAravind Akella if (mWakeLockAcquired && !needsWakeLock) { 4809a844cf78f09953145200b4074d47589257a408cAravind Akella release_wake_lock(WAKE_LOCK_NAME); 4819a844cf78f09953145200b4074d47589257a408cAravind Akella mWakeLockAcquired = false; 4829a844cf78f09953145200b4074d47589257a408cAravind Akella ALOGD_IF(DEBUG_CONNECTIONS, "released wakelock %s", WAKE_LOCK_NAME); 4839a844cf78f09953145200b4074d47589257a408cAravind Akella } 484fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } while (count >= 0 || Thread::exitPending()); 485fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 4863c20fbed7f3a916ced10f2ed5a272271b7d81edeSteve Block ALOGW("Exiting SensorService::threadLoop => aborting..."); 4871a62301fc58cd2af18239b0415813461bf5fc41bMathias Agopian abort(); 488fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return false; 489fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 490fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 49156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellasp<Looper> SensorService::getLooper() const { 49256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella return mLooper; 49356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella} 49456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 49556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellabool SensorService::SensorEventAckReceiver::threadLoop() { 49656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella ALOGD("new thread SensorEventAckReceiver"); 49756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella do { 49856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella sp<Looper> looper = mService->getLooper(); 49956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella looper->pollOnce(-1); 50056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } while(!Thread::exitPending()); 50156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella return false; 50256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella} 50356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 5049a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::recordLastValueLocked( 5054b84704b97300eff3ebfab85652e64d54149d205Aravind Akella const sensors_event_t* buffer, size_t count) { 5064b84704b97300eff3ebfab85652e64d54149d205Aravind Akella const sensors_event_t* last = NULL; 5074b84704b97300eff3ebfab85652e64d54149d205Aravind Akella for (size_t i = 0; i < count; i++) { 5084b84704b97300eff3ebfab85652e64d54149d205Aravind Akella const sensors_event_t* event = &buffer[i]; 5094b84704b97300eff3ebfab85652e64d54149d205Aravind Akella if (event->type != SENSOR_TYPE_META_DATA) { 5104b84704b97300eff3ebfab85652e64d54149d205Aravind Akella if (last && event->sensor != last->sensor) { 5114b84704b97300eff3ebfab85652e64d54149d205Aravind Akella mLastEventSeen.editValueFor(last->sensor) = *last; 5124b84704b97300eff3ebfab85652e64d54149d205Aravind Akella } 5134b84704b97300eff3ebfab85652e64d54149d205Aravind Akella last = event; 51494e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian } 51594e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian } 5164b84704b97300eff3ebfab85652e64d54149d205Aravind Akella if (last) { 5174b84704b97300eff3ebfab85652e64d54149d205Aravind Akella mLastEventSeen.editValueFor(last->sensor) = *last; 5184b84704b97300eff3ebfab85652e64d54149d205Aravind Akella } 51994e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian} 52094e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian 521f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopianvoid SensorService::sortEventBuffer(sensors_event_t* buffer, size_t count) 522f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{ 523f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian struct compar { 524f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian static int cmp(void const* lhs, void const* rhs) { 525f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sensors_event_t const* l = static_cast<sensors_event_t const*>(lhs); 526f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian sensors_event_t const* r = static_cast<sensors_event_t const*>(rhs); 527a5c106a4f0afcf061728a1cb7c8c3b908728575dMathias Agopian return l->timestamp - r->timestamp; 528f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 529f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian }; 530f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian qsort(buffer, count, sizeof(sensors_event_t), compar::cmp); 531f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian} 532f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian 5335d2707214dfb97bd8dfcc6620be36841d3c82420Mathias AgopianString8 SensorService::getSensorName(int handle) const { 534010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian size_t count = mUserSensorList.size(); 5355d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian for (size_t i=0 ; i<count ; i++) { 536010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian const Sensor& sensor(mUserSensorList[i]); 5375d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian if (sensor.getHandle() == handle) { 5385d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian return sensor.getName(); 5395d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian } 5405d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian } 5415d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian String8 result("unknown"); 5425d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian return result; 5435d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian} 5445d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian 545b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akellabool SensorService::isVirtualSensor(int handle) const { 546b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella SensorInterface* sensor = mSensorMap.valueFor(handle); 547b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella return sensor->isVirtual(); 548b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella} 549b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella 5509a844cf78f09953145200b4074d47589257a408cAravind Akellabool SensorService::isWakeUpSensorEvent(const sensors_event_t& event) const { 5517869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan int handle = event.sensor; 5527869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan if (event.type == SENSOR_TYPE_META_DATA) { 5537869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan handle = event.meta_data.sensor; 5547869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan } 5557869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan SensorInterface* sensor = mSensorMap.valueFor(handle); 5567869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan return sensor != NULL && sensor->getSensor().isWakeUpSensor(); 5579a844cf78f09953145200b4074d47589257a408cAravind Akella} 5589a844cf78f09953145200b4074d47589257a408cAravind Akella 5596c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 5606c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind AkellaSensorService::SensorRecord * SensorService::getSensorRecord(int handle) { 5616c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella return mActiveSensors.valueFor(handle); 5626c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella} 5636c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 564fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianVector<Sensor> SensorService::getSensorList() 565fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 56633264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian char value[PROPERTY_VALUE_MAX]; 56733264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian property_get("debug.sensors", value, "0"); 568700180487ffec09d9df1657b018a7caadac24b75Aravind Akella const Vector<Sensor>& initialSensorList = (atoi(value)) ? 569700180487ffec09d9df1657b018a7caadac24b75Aravind Akella mUserSensorListDebug : mUserSensorList; 570700180487ffec09d9df1657b018a7caadac24b75Aravind Akella Vector<Sensor> accessibleSensorList; 571700180487ffec09d9df1657b018a7caadac24b75Aravind Akella for (size_t i = 0; i < initialSensorList.size(); i++) { 572700180487ffec09d9df1657b018a7caadac24b75Aravind Akella Sensor sensor = initialSensorList[i]; 573700180487ffec09d9df1657b018a7caadac24b75Aravind Akella if (canAccessSensor(sensor)) { 574700180487ffec09d9df1657b018a7caadac24b75Aravind Akella accessibleSensorList.add(sensor); 575700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } else { 576700180487ffec09d9df1657b018a7caadac24b75Aravind Akella String8 infoMessage; 577700180487ffec09d9df1657b018a7caadac24b75Aravind Akella infoMessage.appendFormat( 578700180487ffec09d9df1657b018a7caadac24b75Aravind Akella "Skipped sensor %s because it requires permission %s", 579700180487ffec09d9df1657b018a7caadac24b75Aravind Akella sensor.getName().string(), 580700180487ffec09d9df1657b018a7caadac24b75Aravind Akella sensor.getRequiredPermission().string()); 581700180487ffec09d9df1657b018a7caadac24b75Aravind Akella ALOGI(infoMessage.string()); 582700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } 58333264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian } 584700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return accessibleSensorList; 585fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 586fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 587fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopiansp<ISensorEventConnection> SensorService::createSensorEventConnection() 588fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 5895307d17fe33fc26eeeacd6339a9fbfe96cf56873Mathias Agopian uid_t uid = IPCThreadState::self()->getCallingUid(); 5905307d17fe33fc26eeeacd6339a9fbfe96cf56873Mathias Agopian sp<SensorEventConnection> result(new SensorEventConnection(this, uid)); 591fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return result; 592fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 593fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 594db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopianvoid SensorService::cleanupConnection(SensorEventConnection* c) 595fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 596fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian Mutex::Autolock _l(mLock); 597db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian const wp<SensorEventConnection> connection(c); 5987c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian size_t size = mActiveSensors.size(); 599db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn ALOGD_IF(DEBUG_CONNECTIONS, "%zu active sensors", size); 6007c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian for (size_t i=0 ; i<size ; ) { 601db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian int handle = mActiveSensors.keyAt(i); 602db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian if (c->hasSensor(handle)) { 603db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn ALOGD_IF(DEBUG_CONNECTIONS, "%zu: disabling handle=0x%08x", i, handle); 604f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian SensorInterface* sensor = mSensorMap.valueFor( handle ); 605f5a1230d322c14c42331d0a1536b50c87742973bSteve Block ALOGE_IF(!sensor, "mSensorMap[handle=0x%08x] is null!", handle); 606f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian if (sensor) { 607db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian sensor->activate(c, false); 608f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 609db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian } 610db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian SensorRecord* rec = mActiveSensors.valueAt(i); 611db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn ALOGE_IF(!rec, "mActiveSensors[%zu] is null (handle=0x%08x)!", i, handle); 612a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block ALOGD_IF(DEBUG_CONNECTIONS, 613db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn "removing connection %p for sensor[%zu].handle=0x%08x", 614a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian c, i, handle); 615a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian 616db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian if (rec && rec->removeConnection(connection)) { 617a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block ALOGD_IF(DEBUG_CONNECTIONS, "... and it was the last connection"); 6187c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian mActiveSensors.removeItemsAt(i, 1); 619f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian mActiveVirtualSensors.removeItem(handle); 6207c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian delete rec; 6217c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian size--; 6227c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian } else { 6237c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian i++; 624fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 625fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 6267c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian mActiveConnections.remove(connection); 627787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian BatteryService::cleanup(c->getUid()); 6289a844cf78f09953145200b4074d47589257a408cAravind Akella if (c->needsWakeLock()) { 6299a844cf78f09953145200b4074d47589257a408cAravind Akella checkWakeLockStateLocked(); 6309a844cf78f09953145200b4074d47589257a408cAravind Akella } 631fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 632fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 633700180487ffec09d9df1657b018a7caadac24b75Aravind AkellaSensor SensorService::getSensorFromHandle(int handle) const { 634700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return mSensorMap.valueFor(handle)->getSensor(); 635700180487ffec09d9df1657b018a7caadac24b75Aravind Akella} 636700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 637fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::enable(const sp<SensorEventConnection>& connection, 638724d91d778e71c8186399f4955de14b54812b3edAravind Akella int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags) 639fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 64050df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian if (mInitCheck != NO_ERROR) 64150df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian return mInitCheck; 64250df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian 643f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian SensorInterface* sensor = mSensorMap.valueFor(handle); 644ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian if (sensor == NULL) { 645ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian return BAD_VALUE; 646ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian } 647700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 648700180487ffec09d9df1657b018a7caadac24b75Aravind Akella if (!verifyCanAccessSensor(sensor->getSensor(), "Tried enabling")) { 649700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return BAD_VALUE; 650700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } 651700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 652ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian Mutex::Autolock _l(mLock); 6534342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh SensorRecord* rec = mActiveSensors.valueFor(handle); 6544342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (rec == 0) { 6554342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh rec = new SensorRecord(connection); 6564342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh mActiveSensors.add(handle, rec); 6574342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (sensor->isVirtual()) { 6584342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh mActiveVirtualSensors.add(handle, sensor); 6593560fb24b668675627934356f210d84d19bf4e56Mathias Agopian } 6604342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } else { 6614342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (rec->addConnection(connection)) { 6629a844cf78f09953145200b4074d47589257a408cAravind Akella // this sensor is already activated, but we are adding a connection that uses it. 6639a844cf78f09953145200b4074d47589257a408cAravind Akella // Immediately send down the last known value of the requested sensor if it's not a 6644342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // "continuous" sensor. 6650e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ON_CHANGE) { 6669a844cf78f09953145200b4074d47589257a408cAravind Akella // NOTE: The wake_up flag of this event may get set to 6679a844cf78f09953145200b4074d47589257a408cAravind Akella // WAKE_UP_SENSOR_EVENT_NEEDS_ACK if this is a wake_up event. 6684342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh sensors_event_t& event(mLastEventSeen.editValueFor(handle)); 6694342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (event.version == sizeof(sensors_event_t)) { 6709a844cf78f09953145200b4074d47589257a408cAravind Akella if (isWakeUpSensorEvent(event) && !mWakeLockAcquired) { 6719a844cf78f09953145200b4074d47589257a408cAravind Akella acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME); 6729a844cf78f09953145200b4074d47589257a408cAravind Akella mWakeLockAcquired = true; 6739a844cf78f09953145200b4074d47589257a408cAravind Akella ALOGD_IF(DEBUG_CONNECTIONS, "acquired wakelock for on_change sensor %s", 6749a844cf78f09953145200b4074d47589257a408cAravind Akella WAKE_LOCK_NAME); 6759a844cf78f09953145200b4074d47589257a408cAravind Akella } 6769a844cf78f09953145200b4074d47589257a408cAravind Akella connection->sendEvents(&event, 1, NULL); 6779a844cf78f09953145200b4074d47589257a408cAravind Akella if (!connection->needsWakeLock() && mWakeLockAcquired) { 6789a844cf78f09953145200b4074d47589257a408cAravind Akella checkWakeLockStateLocked(); 6799a844cf78f09953145200b4074d47589257a408cAravind Akella } 680f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian } 6817c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian } 682fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 683fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 6844342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 6854342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (connection->addSensor(handle)) { 6864342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh BatteryService::enableSensor(connection->getUid(), handle); 6874342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // the sensor was added (which means it wasn't already there) 6884342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh // so, see if this connection becomes active 6894342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (mActiveConnections.indexOf(connection) < 0) { 6904342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh mActiveConnections.add(connection); 6914342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 6924342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } else { 6934342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh ALOGW("sensor %08x already enabled in connection %p (ignoring)", 6944342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh handle, connection.get()); 6954342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 6964342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 697724d91d778e71c8186399f4955de14b54812b3edAravind Akella nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs(); 698724d91d778e71c8186399f4955de14b54812b3edAravind Akella if (samplingPeriodNs < minDelayNs) { 699724d91d778e71c8186399f4955de14b54812b3edAravind Akella samplingPeriodNs = minDelayNs; 700724d91d778e71c8186399f4955de14b54812b3edAravind Akella } 701724d91d778e71c8186399f4955de14b54812b3edAravind Akella 7026c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d" 7036c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella "rate=%" PRId64 " timeout== %" PRId64"", 704724d91d778e71c8186399f4955de14b54812b3edAravind Akella handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs); 705724d91d778e71c8186399f4955de14b54812b3edAravind Akella 706724d91d778e71c8186399f4955de14b54812b3edAravind Akella status_t err = sensor->batch(connection.get(), handle, reservedFlags, samplingPeriodNs, 707724d91d778e71c8186399f4955de14b54812b3edAravind Akella maxBatchReportLatencyNs); 7086c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 7095466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // Call flush() before calling activate() on the sensor. Wait for a first flush complete 7105466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // event before sending events on this connection. Ignore one-shot sensors which don't 7115466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // support flush(). Also if this sensor isn't already active, don't call flush(). 7125466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella if (err == NO_ERROR && sensor->getSensor().getReportingMode() != AREPORTING_MODE_ONE_SHOT && 7135466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella rec->getNumConnections() > 1) { 7145466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella connection->setFirstFlushPending(handle, true); 7154c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella status_t err_flush = sensor->flush(connection.get(), handle); 7165466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // Flush may return error if the underlying h/w sensor uses an older HAL. 7176c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella if (err_flush == NO_ERROR) { 7186c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella rec->addPendingFlushConnection(connection.get()); 7195466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella } else { 7205466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella connection->setFirstFlushPending(handle, false); 7214c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 7224c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 723724d91d778e71c8186399f4955de14b54812b3edAravind Akella 724724d91d778e71c8186399f4955de14b54812b3edAravind Akella if (err == NO_ERROR) { 725724d91d778e71c8186399f4955de14b54812b3edAravind Akella ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle); 726724d91d778e71c8186399f4955de14b54812b3edAravind Akella err = sensor->activate(connection.get(), true); 727724d91d778e71c8186399f4955de14b54812b3edAravind Akella } 728724d91d778e71c8186399f4955de14b54812b3edAravind Akella 72956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella if (err == NO_ERROR && sensor->getSensor().isWakeUpSensor()) { 73056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // Add the file descriptor to the Looper for receiving acknowledgments; 73156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella int ret = mLooper->addFd(connection->getSensorChannel()->getSendFd(), 0, 73256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella ALOOPER_EVENT_INPUT, connection.get(), NULL); 73356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 73456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 7354342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (err != NO_ERROR) { 736724d91d778e71c8186399f4955de14b54812b3edAravind Akella // batch/activate has failed, reset our state. 737ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian cleanupWithoutDisableLocked(connection, handle); 7384342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 739fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return err; 740fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 741fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 742fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::disable(const sp<SensorEventConnection>& connection, 743fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian int handle) 744fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 74550df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian if (mInitCheck != NO_ERROR) 74650df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian return mInitCheck; 74750df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian 748ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian Mutex::Autolock _l(mLock); 749ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian status_t err = cleanupWithoutDisableLocked(connection, handle); 7504342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh if (err == NO_ERROR) { 7514342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh SensorInterface* sensor = mSensorMap.valueFor(handle); 7524342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh err = sensor ? sensor->activate(connection.get(), false) : status_t(BAD_VALUE); 7534342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh } 7544342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh return err; 7554342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh} 7564342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh 757ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisable( 758ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian const sp<SensorEventConnection>& connection, int handle) { 759fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian Mutex::Autolock _l(mLock); 760ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian return cleanupWithoutDisableLocked(connection, handle); 761ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian} 762ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian 763ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisableLocked( 764ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian const sp<SensorEventConnection>& connection, int handle) { 765fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian SensorRecord* rec = mActiveSensors.valueFor(handle); 766fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian if (rec) { 767fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian // see if this connection becomes inactive 768787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian if (connection->removeSensor(handle)) { 769787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian BatteryService::disableSensor(connection->getUid(), handle); 770787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian } 771fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian if (connection->hasAnySensor() == false) { 772fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian mActiveConnections.remove(connection); 773fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 774fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian // see if this sensor becomes inactive 775fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian if (rec->removeConnection(connection)) { 776fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian mActiveSensors.removeItem(handle); 777f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian mActiveVirtualSensors.removeItem(handle); 778fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian delete rec; 779fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 7804342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh return NO_ERROR; 7817c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian } 7824342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh return BAD_VALUE; 783fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 784fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 7857c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianstatus_t SensorService::setEventRate(const sp<SensorEventConnection>& connection, 786fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian int handle, nsecs_t ns) 787fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 78850df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian if (mInitCheck != NO_ERROR) 78950df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian return mInitCheck; 79050df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian 791ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian SensorInterface* sensor = mSensorMap.valueFor(handle); 792ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian if (!sensor) 793ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian return BAD_VALUE; 794ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian 795700180487ffec09d9df1657b018a7caadac24b75Aravind Akella if (!verifyCanAccessSensor(sensor->getSensor(), "Tried configuring")) { 796700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return BAD_VALUE; 797700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } 798700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 7991cd700015318727d6d42236ab6274f1949fb08baMathias Agopian if (ns < 0) 8001cd700015318727d6d42236ab6274f1949fb08baMathias Agopian return BAD_VALUE; 8011cd700015318727d6d42236ab6274f1949fb08baMathias Agopian 80262569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs(); 80362569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian if (ns < minDelayNs) { 80462569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian ns = minDelayNs; 805ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian } 806ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian 807f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian return sensor->setDelay(connection.get(), handle, ns); 808fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 809fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 8109e3adfcebf28c5c76085108dffe98c74df56857dAravind Akellastatus_t SensorService::flushSensor(const sp<SensorEventConnection>& connection) { 811700180487ffec09d9df1657b018a7caadac24b75Aravind Akella if (mInitCheck != NO_ERROR) return mInitCheck; 8129e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella SensorDevice& dev(SensorDevice::getInstance()); 8139e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella const int halVersion = dev.getHalDeviceVersion(); 8149e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella status_t err(NO_ERROR); 8159e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella Mutex::Autolock _l(mLock); 8169e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // Loop through all sensors for this connection and call flush on each of them. 8179e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella for (size_t i = 0; i < connection->mSensorInfo.size(); ++i) { 8189e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella const int handle = connection->mSensorInfo.keyAt(i); 8199e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella SensorInterface* sensor = mSensorMap.valueFor(handle); 8209e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) { 8219e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella ALOGE("flush called on a one-shot sensor"); 8229e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella err = INVALID_OPERATION; 8239e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella continue; 8249e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } 8259e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella SensorEventConnection::FlushInfo& flushInfo = connection->mSensorInfo.editValueFor(handle); 8269e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella if (halVersion < SENSORS_DEVICE_API_VERSION_1_1 || isVirtualSensor(handle)) { 8279e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // For older devices just increment pending flush count which will send a trivial 8289e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // flush complete event. 8299e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella flushInfo.mPendingFlushEventsToSend++; 8309e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } else { 8319e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella status_t err_flush = sensor->flush(connection.get(), handle); 8329e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella if (err_flush == NO_ERROR) { 8339e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella SensorRecord* rec = mActiveSensors.valueFor(handle); 8349e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella if (rec != NULL) rec->addPendingFlushConnection(connection); 8359e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } 8369e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella err = (err_flush != NO_ERROR) ? err_flush : err; 8379e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } 8386c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } 8399e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella return err; 840700180487ffec09d9df1657b018a7caadac24b75Aravind Akella} 841700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 842700180487ffec09d9df1657b018a7caadac24b75Aravind Akellabool SensorService::canAccessSensor(const Sensor& sensor) { 84356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella return (sensor.getRequiredPermission().isEmpty()) || 84456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella PermissionCache::checkCallingPermission(String16(sensor.getRequiredPermission())); 845724d91d778e71c8186399f4955de14b54812b3edAravind Akella} 846700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 847700180487ffec09d9df1657b018a7caadac24b75Aravind Akellabool SensorService::verifyCanAccessSensor(const Sensor& sensor, const char* operation) { 848700180487ffec09d9df1657b018a7caadac24b75Aravind Akella if (canAccessSensor(sensor)) { 849700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return true; 850700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } else { 851700180487ffec09d9df1657b018a7caadac24b75Aravind Akella String8 errorMessage; 852700180487ffec09d9df1657b018a7caadac24b75Aravind Akella errorMessage.appendFormat( 853700180487ffec09d9df1657b018a7caadac24b75Aravind Akella "%s a sensor (%s) without holding its required permission: %s", 854700180487ffec09d9df1657b018a7caadac24b75Aravind Akella operation, 855700180487ffec09d9df1657b018a7caadac24b75Aravind Akella sensor.getName().string(), 856700180487ffec09d9df1657b018a7caadac24b75Aravind Akella sensor.getRequiredPermission().string()); 857700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return false; 858700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } 859700180487ffec09d9df1657b018a7caadac24b75Aravind Akella} 860700180487ffec09d9df1657b018a7caadac24b75Aravind Akella 8619a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockState() { 8629a844cf78f09953145200b4074d47589257a408cAravind Akella Mutex::Autolock _l(mLock); 8639a844cf78f09953145200b4074d47589257a408cAravind Akella checkWakeLockStateLocked(); 8649a844cf78f09953145200b4074d47589257a408cAravind Akella} 8659a844cf78f09953145200b4074d47589257a408cAravind Akella 8669a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockStateLocked() { 8679a844cf78f09953145200b4074d47589257a408cAravind Akella if (!mWakeLockAcquired) { 8689a844cf78f09953145200b4074d47589257a408cAravind Akella return; 8699a844cf78f09953145200b4074d47589257a408cAravind Akella } 8709a844cf78f09953145200b4074d47589257a408cAravind Akella bool releaseLock = true; 8719a844cf78f09953145200b4074d47589257a408cAravind Akella for (size_t i=0 ; i<mActiveConnections.size() ; i++) { 8729a844cf78f09953145200b4074d47589257a408cAravind Akella sp<SensorEventConnection> connection(mActiveConnections[i].promote()); 8739a844cf78f09953145200b4074d47589257a408cAravind Akella if (connection != 0) { 8749a844cf78f09953145200b4074d47589257a408cAravind Akella if (connection->needsWakeLock()) { 8759a844cf78f09953145200b4074d47589257a408cAravind Akella releaseLock = false; 8769a844cf78f09953145200b4074d47589257a408cAravind Akella break; 8779a844cf78f09953145200b4074d47589257a408cAravind Akella } 8789a844cf78f09953145200b4074d47589257a408cAravind Akella } 8799a844cf78f09953145200b4074d47589257a408cAravind Akella } 8809a844cf78f09953145200b4074d47589257a408cAravind Akella if (releaseLock) { 8819a844cf78f09953145200b4074d47589257a408cAravind Akella ALOGD_IF(DEBUG_CONNECTIONS, "releasing wakelock %s", WAKE_LOCK_NAME); 8829a844cf78f09953145200b4074d47589257a408cAravind Akella release_wake_lock(WAKE_LOCK_NAME); 8839a844cf78f09953145200b4074d47589257a408cAravind Akella mWakeLockAcquired = false; 8849a844cf78f09953145200b4074d47589257a408cAravind Akella } 8859a844cf78f09953145200b4074d47589257a408cAravind Akella} 8866c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 887fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// --------------------------------------------------------------------------- 888fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorRecord::SensorRecord( 889fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian const sp<SensorEventConnection>& connection) 890fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 891fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian mConnections.add(connection); 892fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 893fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 8947c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianbool SensorService::SensorRecord::addConnection( 895fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian const sp<SensorEventConnection>& connection) 896fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 897fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian if (mConnections.indexOf(connection) < 0) { 898fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian mConnections.add(connection); 8997c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian return true; 900fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 9017c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian return false; 902fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 903fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 904fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::SensorRecord::removeConnection( 905fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian const wp<SensorEventConnection>& connection) 906fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 907fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian ssize_t index = mConnections.indexOf(connection); 908fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian if (index >= 0) { 909fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian mConnections.removeItemsAt(index, 1); 910fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 9116c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella // Remove this connections from the queue of flush() calls made on this sensor. 9126c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella for (Vector< wp<SensorEventConnection> >::iterator it = 9136c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella mPendingFlushConnections.begin(); it != mPendingFlushConnections.end();) { 9146c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella if (it->unsafe_get() == connection.unsafe_get()) { 9156c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella it = mPendingFlushConnections.erase(it); 9166c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } else { 9176c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella ++it; 9186c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } 9196c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } 920fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return mConnections.size() ? false : true; 921fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 922fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 9236c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akellavoid SensorService::SensorRecord::addPendingFlushConnection( 9246c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella const sp<SensorEventConnection>& connection) { 9256c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella mPendingFlushConnections.add(connection); 9266c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella} 9276c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 9286c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akellavoid SensorService::SensorRecord::removeFirstPendingFlushConnection() { 9296c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella if (mPendingFlushConnections.size() > 0) { 9306c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella mPendingFlushConnections.removeAt(0); 9316c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } 9326c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella} 9336c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 9346c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind AkellaSensorService::SensorEventConnection * 9356c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind AkellaSensorService::SensorRecord::getFirstPendingFlushConnection() { 9366c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella if (mPendingFlushConnections.size() > 0) { 9376c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella return mPendingFlushConnections[0].unsafe_get(); 9386c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } 9396c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella return NULL; 9406c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella} 9416c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 942fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// --------------------------------------------------------------------------- 943fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 944fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorEventConnection::SensorEventConnection( 9455307d17fe33fc26eeeacd6339a9fbfe96cf56873Mathias Agopian const sp<SensorService>& service, uid_t uid) 94656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella : mService(service), mUid(uid), mWakeLockRefCount(0), mEventCache(NULL), mCacheSize(0), 94756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella mMaxCacheSize(0) { 9484c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella const SensorDevice& device(SensorDevice::getInstance()); 9495466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella mChannel = new BitTube(mService->mSocketBufferSize); 95056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#if DEBUG_CONNECTIONS 95156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella mEventsReceived = mEventsSentFromCache = mEventsSent = 0; 952e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella mTotalAcksNeeded = mTotalAcksReceived = 0; 95356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#endif 954fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 955fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 95656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind AkellaSensorService::SensorEventConnection::~SensorEventConnection() { 957a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block ALOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this); 95856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella if (mEventCache != NULL) { 95956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella delete mEventCache; 96056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 961fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian mService->cleanupConnection(this); 962fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 963fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 96456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellavoid SensorService::SensorEventConnection::onFirstRef() { 96556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella LooperCallback::onFirstRef(); 966fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 967fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 9689a844cf78f09953145200b4074d47589257a408cAravind Akellabool SensorService::SensorEventConnection::needsWakeLock() { 9699a844cf78f09953145200b4074d47589257a408cAravind Akella Mutex::Autolock _l(mConnectionLock); 9709a844cf78f09953145200b4074d47589257a408cAravind Akella return mWakeLockRefCount > 0; 9719a844cf78f09953145200b4074d47589257a408cAravind Akella} 9729a844cf78f09953145200b4074d47589257a408cAravind Akella 9734c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akellavoid SensorService::SensorEventConnection::dump(String8& result) { 9744c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella Mutex::Autolock _l(mConnectionLock); 97556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella result.appendFormat("\t %d WakeLockRefCount \n", mWakeLockRefCount); 9764c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella for (size_t i = 0; i < mSensorInfo.size(); ++i) { 9774c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella const FlushInfo& flushInfo = mSensorInfo.valueAt(i); 9786c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella result.appendFormat("\t %s 0x%08x | status: %s | pending flush events %d | uid %d|" 97956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella "cache size: %d max cache size %d\n", 9804c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella mService->getSensorName(mSensorInfo.keyAt(i)).string(), 9816c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella mSensorInfo.keyAt(i), 9824c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella flushInfo.mFirstFlushPending ? "First flush pending" : 9834c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella "active", 984eefced119bc568d773b86c34cd8bc9d9574638f6Patrick Tjin flushInfo.mPendingFlushEventsToSend, 98556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella mUid, 98656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella mCacheSize, 98756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella mMaxCacheSize); 98856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#if DEBUG_CONNECTIONS 989e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella result.appendFormat("\t events recvd: %d | sent %d | cache %d | dropped %d |" 990e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella " total_acks_needed %d | total_acks_recvd %d\n", 99156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella mEventsReceived, 99256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella mEventsSent, 99356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella mEventsSentFromCache, 994e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella mEventsReceived - (mEventsSentFromCache + 995e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella mEventsSent + mCacheSize), 996e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella mTotalAcksNeeded, 997e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella mTotalAcksReceived); 99856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#endif 99956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 10004c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 10014c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella} 10024c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella 10037c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianbool SensorService::SensorEventConnection::addSensor(int32_t handle) { 100471d7a5c289c6ef6b5fc86dd4784a075ca6470e38Mathias Agopian Mutex::Autolock _l(mConnectionLock); 1005700180487ffec09d9df1657b018a7caadac24b75Aravind Akella if (!verifyCanAccessSensor(mService->getSensorFromHandle(handle), "Tried adding")) { 1006700180487ffec09d9df1657b018a7caadac24b75Aravind Akella return false; 1007700180487ffec09d9df1657b018a7caadac24b75Aravind Akella } 10084c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella if (mSensorInfo.indexOfKey(handle) < 0) { 10094c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella mSensorInfo.add(handle, FlushInfo()); 10107c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian return true; 1011fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 10127c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian return false; 1013fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 1014fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 10157c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianbool SensorService::SensorEventConnection::removeSensor(int32_t handle) { 101671d7a5c289c6ef6b5fc86dd4784a075ca6470e38Mathias Agopian Mutex::Autolock _l(mConnectionLock); 10174c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella if (mSensorInfo.removeItem(handle) >= 0) { 10187c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian return true; 10197c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian } 10207c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian return false; 1021fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 1022fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 1023fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::SensorEventConnection::hasSensor(int32_t handle) const { 102471d7a5c289c6ef6b5fc86dd4784a075ca6470e38Mathias Agopian Mutex::Autolock _l(mConnectionLock); 10254c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella return mSensorInfo.indexOfKey(handle) >= 0; 1026fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 1027fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 1028fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::SensorEventConnection::hasAnySensor() const { 102971d7a5c289c6ef6b5fc86dd4784a075ca6470e38Mathias Agopian Mutex::Autolock _l(mConnectionLock); 10307c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian return mSensorInfo.size() ? true : false; 10317c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian} 10327c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian 10334c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akellavoid SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle, 10344c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella bool value) { 10354c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella Mutex::Autolock _l(mConnectionLock); 10364c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella ssize_t index = mSensorInfo.indexOfKey(handle); 10374c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella if (index >= 0) { 10384c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella FlushInfo& flushInfo = mSensorInfo.editValueAt(index); 10394c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella flushInfo.mFirstFlushPending = value; 10404c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 10414c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella} 10424c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella 1043fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::SensorEventConnection::sendEvents( 10449e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella sensors_event_t* buffer, size_t numEvents, 104556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella sensors_event_t* scratch) { 1046cf51001dbf28e9885fcacd4048902f1c75768fe9Mathias Agopian // filter out events not for this connection 10473560fb24b668675627934356f210d84d19bf4e56Mathias Agopian size_t count = 0; 10489a844cf78f09953145200b4074d47589257a408cAravind Akella Mutex::Autolock _l(mConnectionLock); 10493560fb24b668675627934356f210d84d19bf4e56Mathias Agopian if (scratch) { 10503560fb24b668675627934356f210d84d19bf4e56Mathias Agopian size_t i=0; 10513560fb24b668675627934356f210d84d19bf4e56Mathias Agopian while (i<numEvents) { 10529e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // Flush complete events can be invalidated. If this event has been invalidated 10539e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // before, ignore and proceed to the next event. 10549e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella if (buffer[i].flags & SENSOR_EVENT_INVALID_FLAG) { 10559e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella ++i; 10569e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella continue; 10579e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } 10586c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella int32_t sensor_handle = buffer[i].sensor; 1059724d91d778e71c8186399f4955de14b54812b3edAravind Akella if (buffer[i].type == SENSOR_TYPE_META_DATA) { 1060724d91d778e71c8186399f4955de14b54812b3edAravind Akella ALOGD_IF(DEBUG_CONNECTIONS, "flush complete event sensor==%d ", 10619e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella buffer[i].meta_data.sensor); 10626c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella // Setting sensor_handle to the correct sensor to ensure the sensor events per connection are 1063724d91d778e71c8186399f4955de14b54812b3edAravind Akella // filtered correctly. buffer[i].sensor is zero for meta_data events. 10646c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella sensor_handle = buffer[i].meta_data.sensor; 1065724d91d778e71c8186399f4955de14b54812b3edAravind Akella } 10666c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella ssize_t index = mSensorInfo.indexOfKey(sensor_handle); 106756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // Check if this connection has registered for this sensor. If not continue to the 106856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // next sensor_event. 106956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella if (index < 0) { 107056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella ++i; 107156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella continue; 10724c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 107356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 107456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella FlushInfo& flushInfo = mSensorInfo.editValueAt(index); 10756c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella // Check if there is a pending flush_complete event for this sensor on this connection. 10766c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella if (buffer[i].type == SENSOR_TYPE_META_DATA && flushInfo.mFirstFlushPending == true) { 10776c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella SensorService::SensorRecord *rec = mService->getSensorRecord(sensor_handle); 10786c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella if (rec && rec->getFirstPendingFlushConnection() == this) { 10796c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella rec->removeFirstPendingFlushConnection(); 108056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella flushInfo.mFirstFlushPending = false; 10819e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // Invalidate this flush_complete_event so that it cannot be used by other 10829e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // connections. 10839e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella buffer[i].flags |= SENSOR_EVENT_INVALID_FLAG; 10846c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella ALOGD_IF(DEBUG_CONNECTIONS, "First flush event for sensor==%d ", 10859e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella buffer[i].meta_data.sensor); 10869e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella ++i; 108756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella continue; 108856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 108956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 109056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 109156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // If there is a pending flush complete event for this sensor on this connection, 109256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // ignore the event and proceed to the next. 109356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella if (flushInfo.mFirstFlushPending) { 109456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella ++i; 109556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella continue; 10963560fb24b668675627934356f210d84d19bf4e56Mathias Agopian } 109756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 109856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella do { 10999e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella if (buffer[i].flags & SENSOR_EVENT_INVALID_FLAG) { 11009e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella ++i; 11019e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella continue; 11029e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella } 110356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella if (buffer[i].type == SENSOR_TYPE_META_DATA) { 11049e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // Check if this connection has called flush() on this sensor. Only if 11059e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // a flush() has been explicitly called, send a flush_complete_event. 11069e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella SensorService::SensorRecord *rec = mService->getSensorRecord(sensor_handle); 11079e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella if (rec && rec->getFirstPendingFlushConnection() == this) { 11086c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella rec->removeFirstPendingFlushConnection(); 110956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella scratch[count++] = buffer[i]; 11109e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // Invalidate this flush_complete_event so that it cannot be used by 11119e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella // other connections. 11129e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella buffer[i].flags |= SENSOR_EVENT_INVALID_FLAG; 111356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 111456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella ++i; 111556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } else { 111656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // Regular sensor event, just copy it to the scratch buffer. 111756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella scratch[count++] = buffer[i++]; 111856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 11196c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } while ((i<numEvents) && ((buffer[i].sensor == sensor_handle) || 112056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella (buffer[i].type == SENSOR_TYPE_META_DATA && 11216c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella buffer[i].meta_data.sensor == sensor_handle))); 1122cf51001dbf28e9885fcacd4048902f1c75768fe9Mathias Agopian } 11233560fb24b668675627934356f210d84d19bf4e56Mathias Agopian } else { 11243560fb24b668675627934356f210d84d19bf4e56Mathias Agopian scratch = const_cast<sensors_event_t *>(buffer); 11253560fb24b668675627934356f210d84d19bf4e56Mathias Agopian count = numEvents; 1126cf51001dbf28e9885fcacd4048902f1c75768fe9Mathias Agopian } 1127fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 11286c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella sendPendingFlushEventsLocked(); 112956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // Early return if there are no events for this connection. 113056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella if (count == 0) { 113156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella return status_t(NO_ERROR); 113256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 113356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 113456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#if DEBUG_CONNECTIONS 113556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella mEventsReceived += count; 113656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#endif 113756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella if (mCacheSize != 0) { 113856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // There are some events in the cache which need to be sent first. Copy this buffer to 113956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // the end of cache. 114056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella if (mCacheSize + count <= mMaxCacheSize) { 114156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella memcpy(&mEventCache[mCacheSize], scratch, count * sizeof(sensors_event_t)); 114256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella mCacheSize += count; 114356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } else { 11446c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella // Check if any new sensors have registered on this connection which may have increased 11456c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella // the max cache size that is desired. 11466c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella if (mCacheSize + count < computeMaxCacheSizeLocked()) { 11476c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella reAllocateCacheLocked(scratch, count); 11486c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella return status_t(NO_ERROR); 11496c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } 115056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // Some events need to be dropped. 115156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella int remaningCacheSize = mMaxCacheSize - mCacheSize; 115256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella if (remaningCacheSize != 0) { 115356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella memcpy(&mEventCache[mCacheSize], scratch, 115456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella remaningCacheSize * sizeof(sensors_event_t)); 115556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 115656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella int numEventsDropped = count - remaningCacheSize; 115756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella countFlushCompleteEventsLocked(mEventCache, numEventsDropped); 115856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // Drop the first "numEventsDropped" in the cache. 115956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella memmove(mEventCache, &mEventCache[numEventsDropped], 116056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella (mCacheSize - numEventsDropped) * sizeof(sensors_event_t)); 116156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 116256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // Copy the remainingEvents in scratch buffer to the end of cache. 116356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella memcpy(&mEventCache[mCacheSize - numEventsDropped], scratch + remaningCacheSize, 116456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella numEventsDropped * sizeof(sensors_event_t)); 116556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 116656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella return status_t(NO_ERROR); 116756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 116856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 11696c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella int index_wake_up_event = findWakeUpSensorEventLocked(scratch, count); 11706c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella if (index_wake_up_event >= 0) { 11716c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella scratch[index_wake_up_event].flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK; 11726c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella ++mWakeLockRefCount; 1173e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#if DEBUG_CONNECTIONS 1174e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella ++mTotalAcksNeeded; 1175e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#endif 11766c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } 117756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 117856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // NOTE: ASensorEvent and sensors_event_t are the same type. 117956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella ssize_t size = SensorEventQueue::write(mChannel, 118056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella reinterpret_cast<ASensorEvent const*>(scratch), count); 118156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella if (size < 0) { 118256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // Write error, copy events to local cache. 11836c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella if (index_wake_up_event >= 0) { 11846c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella // If there was a wake_up sensor_event, reset the flag. 11856c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella scratch[index_wake_up_event].flags &= ~WAKE_UP_SENSOR_EVENT_NEEDS_ACK; 11866c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella --mWakeLockRefCount; 1187e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#if DEBUG_CONNECTIONS 1188e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella --mTotalAcksNeeded; 1189e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#endif 11906c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } 119156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella if (mEventCache == NULL) { 119256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella mMaxCacheSize = computeMaxCacheSizeLocked(); 119356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella mEventCache = new sensors_event_t[mMaxCacheSize]; 119456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella mCacheSize = 0; 119556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 119656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella memcpy(&mEventCache[mCacheSize], scratch, count * sizeof(sensors_event_t)); 119756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella mCacheSize += count; 119856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 119956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // Add this file descriptor to the looper to get a callback when this fd is available for 120056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // writing. 120156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella mService->getLooper()->addFd(mChannel->getSendFd(), 0, 120256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella ALOOPER_EVENT_OUTPUT | ALOOPER_EVENT_INPUT, this, NULL); 120356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella return size; 120456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 120556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 120656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#if DEBUG_CONNECTIONS 120756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella if (size > 0) { 120856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella mEventsSent += count; 120956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 121056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#endif 121156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 121256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella return size < 0 ? status_t(size) : status_t(NO_ERROR); 121356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella} 121456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 12156c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akellavoid SensorService::SensorEventConnection::reAllocateCacheLocked(sensors_event_t const* scratch, 12166c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella int count) { 12176c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella sensors_event_t *eventCache_new; 12186c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella const int new_cache_size = computeMaxCacheSizeLocked(); 12196c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella // Allocate new cache, copy over events from the old cache & scratch, free up memory. 12206c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella eventCache_new = new sensors_event_t[new_cache_size]; 12216c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella memcpy(eventCache_new, mEventCache, mCacheSize * sizeof(sensors_event_t)); 12226c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella memcpy(&eventCache_new[mCacheSize], scratch, count * sizeof(sensors_event_t)); 12236c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 12246c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella ALOGD_IF(DEBUG_CONNECTIONS, "reAllocateCacheLocked maxCacheSize=%d %d", mMaxCacheSize, 12256c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella new_cache_size); 12266c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 12276c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella delete mEventCache; 12286c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella mEventCache = eventCache_new; 12296c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella mCacheSize += count; 12306c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella mMaxCacheSize = new_cache_size; 12316c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella} 12326c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 12336c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akellavoid SensorService::SensorEventConnection::sendPendingFlushEventsLocked() { 12346c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella ASensorEvent flushCompleteEvent; 12356c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella flushCompleteEvent.type = SENSOR_TYPE_META_DATA; 12366c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella flushCompleteEvent.sensor = 0; 12376c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella // Loop through all the sensors for this connection and check if there are any pending 12386c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella // flush complete events to be sent. 12396c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella for (size_t i = 0; i < mSensorInfo.size(); ++i) { 12406c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella FlushInfo& flushInfo = mSensorInfo.editValueAt(i); 12416c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella while (flushInfo.mPendingFlushEventsToSend > 0) { 12426c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella flushCompleteEvent.meta_data.sensor = mSensorInfo.keyAt(i); 12436c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella ssize_t size = SensorEventQueue::write(mChannel, &flushCompleteEvent, 1); 12446c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella if (size < 0) { 12456c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella return; 12464c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 12476c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella ALOGD_IF(DEBUG_CONNECTIONS, "sent dropped flush complete event==%d ", 12486c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella flushCompleteEvent.meta_data.sensor); 12496c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella flushInfo.mPendingFlushEventsToSend--; 12504c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 12514c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 12526c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella} 12536c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella 12546c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akellavoid SensorService::SensorEventConnection::writeToSocketFromCacheLocked() { 12555466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // At a time write at most half the size of the receiver buffer in SensorEventQueue OR 12565466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // half the size of the socket buffer allocated in BitTube whichever is smaller. 12575466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella const int maxWriteSize = helpers::min(SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT/2, 12585466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella int(mService->mSocketBufferSize/(sizeof(sensors_event_t)*2))); 12595466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella // Send pending flush complete events (if any) 12606c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella sendPendingFlushEventsLocked(); 126156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella for (int numEventsSent = 0; numEventsSent < mCacheSize;) { 12625466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella const int numEventsToWrite = helpers::min(mCacheSize - numEventsSent, maxWriteSize); 12636c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella int index_wake_up_event = 12646c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella findWakeUpSensorEventLocked(mEventCache + numEventsSent, numEventsToWrite); 12656c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella if (index_wake_up_event >= 0) { 12666c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella mEventCache[index_wake_up_event + numEventsSent].flags |= 12676c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella WAKE_UP_SENSOR_EVENT_NEEDS_ACK; 12686c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella ++mWakeLockRefCount; 1269e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#if DEBUG_CONNECTIONS 1270e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella ++mTotalAcksNeeded; 1271e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#endif 12726c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } 127356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 127456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella ssize_t size = SensorEventQueue::write(mChannel, 127556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella reinterpret_cast<ASensorEvent const*>(mEventCache + numEventsSent), 12766c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella numEventsToWrite); 127756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella if (size < 0) { 12786c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella if (index_wake_up_event >= 0) { 12796c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella // If there was a wake_up sensor_event, reset the flag. 12806c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella mEventCache[index_wake_up_event + numEventsSent].flags &= 12816c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella ~WAKE_UP_SENSOR_EVENT_NEEDS_ACK; 12826c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella --mWakeLockRefCount; 1283e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#if DEBUG_CONNECTIONS 1284e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella --mTotalAcksNeeded; 1285e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#endif 12866c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella } 128756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella memmove(mEventCache, &mEventCache[numEventsSent], 128856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella (mCacheSize - numEventsSent) * sizeof(sensors_event_t)); 128956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella ALOGD_IF(DEBUG_CONNECTIONS, "wrote %d events from cache size==%d ", 12906c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella numEventsSent, mCacheSize); 129156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella mCacheSize -= numEventsSent; 129256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella return; 129356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 12946c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella numEventsSent += numEventsToWrite; 129556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#if DEBUG_CONNECTIONS 12966c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella mEventsSentFromCache += numEventsToWrite; 129756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#endif 1298fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 129956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella ALOGD_IF(DEBUG_CONNECTIONS, "wrote all events from cache size=%d ", mCacheSize); 130056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // All events from the cache have been sent. Reset cache size to zero. 130156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella mCacheSize = 0; 130256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // Poll only for ALOOPER_EVENT_INPUT(read) on the file descriptor. 130356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella mService->getLooper()->addFd(mChannel->getSendFd(), 0, ALOOPER_EVENT_INPUT, this, NULL); 1304fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 1305fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 1306c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akellavoid SensorService::SensorEventConnection::countFlushCompleteEventsLocked( 13074c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella sensors_event_t* scratch, const int numEventsDropped) { 13084c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella ALOGD_IF(DEBUG_CONNECTIONS, "dropping %d events ", numEventsDropped); 13094c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella // Count flushComplete events in the events that are about to the dropped. These will be sent 13104c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella // separately before the next batch of events. 13114c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella for (int j = 0; j < numEventsDropped; ++j) { 13124c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella if (scratch[j].type == SENSOR_TYPE_META_DATA) { 13134c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella FlushInfo& flushInfo = mSensorInfo.editValueFor(scratch[j].meta_data.sensor); 13144c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella flushInfo.mPendingFlushEventsToSend++; 13154c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella ALOGD_IF(DEBUG_CONNECTIONS, "increment pendingFlushCount %d", 13164c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella flushInfo.mPendingFlushEventsToSend); 13174c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 13184c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella } 13194c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella return; 13204c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella} 13214c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella 13226c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akellaint SensorService::SensorEventConnection::findWakeUpSensorEventLocked( 13236c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella sensors_event_t const* scratch, const int count) { 13249a844cf78f09953145200b4074d47589257a408cAravind Akella for (int i = 0; i < count; ++i) { 13259a844cf78f09953145200b4074d47589257a408cAravind Akella if (mService->isWakeUpSensorEvent(scratch[i])) { 13266c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella return i; 13279a844cf78f09953145200b4074d47589257a408cAravind Akella } 13289a844cf78f09953145200b4074d47589257a408cAravind Akella } 13296c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella return -1; 13309a844cf78f09953145200b4074d47589257a408cAravind Akella} 13319a844cf78f09953145200b4074d47589257a408cAravind Akella 1332b3989276d17f2b083bec67b695d1078fb86c6c53Mathias Agopiansp<BitTube> SensorService::SensorEventConnection::getSensorChannel() const 1333fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 1334fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return mChannel; 1335fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 1336fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 1337fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::SensorEventConnection::enableDisable( 1338724d91d778e71c8186399f4955de14b54812b3edAravind Akella int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, 1339724d91d778e71c8186399f4955de14b54812b3edAravind Akella int reservedFlags) 1340fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 1341fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian status_t err; 1342fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian if (enabled) { 1343724d91d778e71c8186399f4955de14b54812b3edAravind Akella err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs, 1344724d91d778e71c8186399f4955de14b54812b3edAravind Akella reservedFlags); 134556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 1346fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } else { 1347fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian err = mService->disable(this, handle); 1348fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian } 1349fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian return err; 1350fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 1351fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 1352fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::SensorEventConnection::setEventRate( 1353724d91d778e71c8186399f4955de14b54812b3edAravind Akella int handle, nsecs_t samplingPeriodNs) 1354fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{ 1355724d91d778e71c8186399f4955de14b54812b3edAravind Akella return mService->setEventRate(this, handle, samplingPeriodNs); 1356fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian} 1357fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 1358701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akellastatus_t SensorService::SensorEventConnection::flush() { 13599e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella return mService->flushSensor(this); 1360724d91d778e71c8186399f4955de14b54812b3edAravind Akella} 13614c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella 136256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellaint SensorService::SensorEventConnection::handleEvent(int fd, int events, void* data) { 136356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella if (events & ALOOPER_EVENT_HANGUP || events & ALOOPER_EVENT_ERROR) { 136456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella return 0; 13659a844cf78f09953145200b4074d47589257a408cAravind Akella } 136656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 136756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella if (events & ALOOPER_EVENT_INPUT) { 136856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella char buf; 136956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella ssize_t ret = ::recv(fd, &buf, sizeof(buf), MSG_DONTWAIT); 137056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 137156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella { 137256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella Mutex::Autolock _l(mConnectionLock); 137356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella --mWakeLockRefCount; 1374e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#if DEBUG_CONNECTIONS 1375e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella ++mTotalAcksReceived; 1376e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#endif 137756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 137856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // Check if wakelock can be released by sensorservice. mConnectionLock needs to be released 137956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // here as checkWakeLockState() will need it. 138056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella if (mWakeLockRefCount == 0) { 138156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella mService->checkWakeLockState(); 138256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 138356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // continue getting callbacks. 138456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella return 1; 138556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 138656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 138756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella if (events & ALOOPER_EVENT_OUTPUT) { 138856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // send sensor data that is stored in mEventCache. 138956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella Mutex::Autolock _l(mConnectionLock); 139056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella writeToSocketFromCacheLocked(); 13919a844cf78f09953145200b4074d47589257a408cAravind Akella } 139256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella return 1; 139356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella} 139456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 139556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellaint SensorService::SensorEventConnection::computeMaxCacheSizeLocked() const { 139656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella int fifoWakeUpSensors = 0; 139756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella int fifoNonWakeUpSensors = 0; 139856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella for (size_t i = 0; i < mSensorInfo.size(); ++i) { 139956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella const Sensor& sensor = mService->getSensorFromHandle(mSensorInfo.keyAt(i)); 140056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella if (sensor.getFifoReservedEventCount() == sensor.getFifoMaxEventCount()) { 140156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // Each sensor has a reserved fifo. Sum up the fifo sizes for all wake up sensors and 140256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // non wake_up sensors. 140356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella if (sensor.isWakeUpSensor()) { 140456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella fifoWakeUpSensors += sensor.getFifoReservedEventCount(); 140556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } else { 140656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella fifoNonWakeUpSensors += sensor.getFifoReservedEventCount(); 140756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 140856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } else { 140956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // Shared fifo. Compute the max of the fifo sizes for wake_up and non_wake up sensors. 141056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella if (sensor.isWakeUpSensor()) { 141156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella fifoWakeUpSensors = fifoWakeUpSensors > sensor.getFifoMaxEventCount() ? 141256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella fifoWakeUpSensors : sensor.getFifoMaxEventCount(); 141356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 141456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } else { 141556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella fifoNonWakeUpSensors = fifoNonWakeUpSensors > sensor.getFifoMaxEventCount() ? 141656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella fifoNonWakeUpSensors : sensor.getFifoMaxEventCount(); 141756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella 141856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 141956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 142056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 142156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella if (fifoWakeUpSensors + fifoNonWakeUpSensors == 0) { 142256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella // It is extremely unlikely that there is a write failure in non batch mode. Return a cache 14236c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella // size that is equal to that of the batch mode. 1424e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella // ALOGW("Write failure in non-batch mode"); 14256c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella return MAX_SOCKET_BUFFER_SIZE_BATCHED/sizeof(sensors_event_t); 142656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella } 142756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella return fifoWakeUpSensors + fifoNonWakeUpSensors; 14289a844cf78f09953145200b4074d47589257a408cAravind Akella} 14299a844cf78f09953145200b4074d47589257a408cAravind Akella 1430fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// --------------------------------------------------------------------------- 1431fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}; // namespace android 1432fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian 1433