SensorService.cpp revision b412f6e203b38f8047f760261a5e3dc6d0722f08
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
34b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav#include <binder/AppOpsManager.h>
35fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <binder/BinderService.h>
36451beee076cac09f817abae78a990dea108a9482Mathias Agopian#include <binder/IServiceManager.h>
371cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian#include <binder/PermissionCache.h>
38fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
39fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <gui/ISensorServer.h>
40fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <gui/ISensorEventConnection.h>
41907103bf186cfdd2ed9eb3b6c36de53ade7b16f6Mathias Agopian#include <gui/SensorEventQueue.h>
42fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
43fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <hardware/sensors.h>
444342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh#include <hardware_legacy/power.h>
45fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
46787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian#include "BatteryService.h"
47984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "CorrectedGyroSensor.h"
48f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "GravitySensor.h"
49f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "LinearAccelerationSensor.h"
50984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "OrientationSensor.h"
51f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "RotationVectorSensor.h"
52984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "SensorFusion.h"
53984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "SensorService.h"
54fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
55fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopiannamespace android {
56fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// ---------------------------------------------------------------------------
57fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
583301542828febc768e1df42892cfac4992c35474Mathias Agopian/*
593301542828febc768e1df42892cfac4992c35474Mathias Agopian * Notes:
603301542828febc768e1df42892cfac4992c35474Mathias Agopian *
613301542828febc768e1df42892cfac4992c35474Mathias Agopian * - what about a gyro-corrected magnetic-field sensor?
623301542828febc768e1df42892cfac4992c35474Mathias Agopian * - run mag sensor from time to time to force calibration
633301542828febc768e1df42892cfac4992c35474Mathias Agopian * - gravity sensor length is wrong (=> drift in linear-acc sensor)
643301542828febc768e1df42892cfac4992c35474Mathias Agopian *
653301542828febc768e1df42892cfac4992c35474Mathias Agopian */
663301542828febc768e1df42892cfac4992c35474Mathias Agopian
674342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganeshconst char* SensorService::WAKE_LOCK_NAME = "SensorService";
68a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella// Permissions.
69a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatic const String16 sDataInjectionPermission("android.permission.HARDWARE_TEST");
70a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatic const String16 sDump("android.permission.DUMP");
714342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
72fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorService()
738a96955c8e14db40b16164236830fc9506a00872Aravind Akella    : mInitCheck(NO_INIT), mSocketBufferSize(SOCKET_BUFFER_SIZE_NON_BATCHED),
748a96955c8e14db40b16164236830fc9506a00872Aravind Akella      mWakeLockAcquired(false)
75fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
76fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
77fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
78fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianvoid SensorService::onFirstRef()
79fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
80a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block    ALOGD("nuSensorService starting...");
81f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    SensorDevice& dev(SensorDevice::getInstance());
82fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
83f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    if (dev.initCheck() == NO_ERROR) {
84f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        sensor_t const* list;
857b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian        ssize_t count = dev.getSensorList(&list);
867b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian        if (count > 0) {
877b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            ssize_t orientationIndex = -1;
887b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            bool hasGyro = false;
897b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            uint32_t virtualSensorsNeeds =
907b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    (1<<SENSOR_TYPE_GRAVITY) |
917b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    (1<<SENSOR_TYPE_LINEAR_ACCELERATION) |
927b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    (1<<SENSOR_TYPE_ROTATION_VECTOR);
937b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian
947b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            mLastEventSeen.setCapacity(count);
957b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            for (ssize_t i=0 ; i<count ; i++) {
967b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                registerSensor( new HardwareSensor(list[i]) );
977b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                switch (list[i].type) {
987b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_ORIENTATION:
997b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        orientationIndex = i;
1007b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        break;
1017b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_GYROSCOPE:
1020319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
1037b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        hasGyro = true;
1047b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        break;
1057b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_GRAVITY:
1067b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_LINEAR_ACCELERATION:
1077b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_ROTATION_VECTOR:
1087b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        virtualSensorsNeeds &= ~(1<<list[i].type);
1097b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        break;
1107b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                }
11150df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian            }
112fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1137b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            // it's safe to instantiate the SensorFusion object here
1147b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            // (it wants to be instantiated after h/w sensors have been
1157b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            // registered)
1167b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            const SensorFusion& fusion(SensorFusion::getInstance());
1177b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian
1180319306670b0344da99efa606b6f172dde575a39Mathias Agopian            // build the sensor list returned to users
1190319306670b0344da99efa606b6f172dde575a39Mathias Agopian            mUserSensorList = mSensorList;
1200319306670b0344da99efa606b6f172dde575a39Mathias Agopian
1217b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            if (hasGyro) {
1220319306670b0344da99efa606b6f172dde575a39Mathias Agopian                Sensor aSensor;
1237b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian
1240319306670b0344da99efa606b6f172dde575a39Mathias Agopian                // Add Android virtual sensors if they're not already
1250319306670b0344da99efa606b6f172dde575a39Mathias Agopian                // available in the HAL
1267b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian
1270319306670b0344da99efa606b6f172dde575a39Mathias Agopian                aSensor = registerVirtualSensor( new RotationVectorSensor() );
1280319306670b0344da99efa606b6f172dde575a39Mathias Agopian                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
1290319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    mUserSensorList.add(aSensor);
1300319306670b0344da99efa606b6f172dde575a39Mathias Agopian                }
131f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
1320319306670b0344da99efa606b6f172dde575a39Mathias Agopian                aSensor = registerVirtualSensor( new GravitySensor(list, count) );
1330319306670b0344da99efa606b6f172dde575a39Mathias Agopian                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) {
1340319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    mUserSensorList.add(aSensor);
1350319306670b0344da99efa606b6f172dde575a39Mathias Agopian                }
13633264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian
1370319306670b0344da99efa606b6f172dde575a39Mathias Agopian                aSensor = registerVirtualSensor( new LinearAccelerationSensor(list, count) );
1380319306670b0344da99efa606b6f172dde575a39Mathias Agopian                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) {
1390319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    mUserSensorList.add(aSensor);
1400319306670b0344da99efa606b6f172dde575a39Mathias Agopian                }
14133264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian
1420319306670b0344da99efa606b6f172dde575a39Mathias Agopian                aSensor = registerVirtualSensor( new OrientationSensor() );
1430319306670b0344da99efa606b6f172dde575a39Mathias Agopian                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
1440319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    // if we are doing our own rotation-vector, also add
1450319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    // the orientation sensor and remove the HAL provided one.
1460319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    mUserSensorList.replaceAt(aSensor, orientationIndex);
1477b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                }
1480319306670b0344da99efa606b6f172dde575a39Mathias Agopian
1490319306670b0344da99efa606b6f172dde575a39Mathias Agopian                // virtual debugging sensors are not added to mUserSensorList
1500319306670b0344da99efa606b6f172dde575a39Mathias Agopian                registerVirtualSensor( new CorrectedGyroSensor(list, count) );
1510319306670b0344da99efa606b6f172dde575a39Mathias Agopian                registerVirtualSensor( new GyroDriftSensor() );
152010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian            }
153010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian
15433264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian            // debugging sensor list
1550319306670b0344da99efa606b6f172dde575a39Mathias Agopian            mUserSensorListDebug = mSensorList;
15633264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian
1575466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            // Check if the device really supports batching by looking at the FIFO event
1585466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            // counts for each sensor.
1595466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            bool batchingSupported = false;
160b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            for (size_t i = 0; i < mSensorList.size(); ++i) {
1615466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                if (mSensorList[i].getFifoMaxEventCount() > 0) {
1625466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                    batchingSupported = true;
1635466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                    break;
1645466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                }
1655466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            }
1665466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella
1675466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            if (batchingSupported) {
1685466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                // Increase socket buffer size to a max of 100 KB for batching capabilities.
1695466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                mSocketBufferSize = MAX_SOCKET_BUFFER_SIZE_BATCHED;
1705466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            } else {
1715466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                mSocketBufferSize = SOCKET_BUFFER_SIZE_NON_BATCHED;
1725466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            }
1735466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella
1745466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            // Compare the socketBufferSize value against the system limits and limit
1755466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            // it to maxSystemSocketBufferSize if necessary.
1764c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            FILE *fp = fopen("/proc/sys/net/core/wmem_max", "r");
1774c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            char line[128];
1784c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            if (fp != NULL && fgets(line, sizeof(line), fp) != NULL) {
1794c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                line[sizeof(line) - 1] = '\0';
1805466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                size_t maxSystemSocketBufferSize;
1815466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                sscanf(line, "%zu", &maxSystemSocketBufferSize);
1825466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                if (mSocketBufferSize > maxSystemSocketBufferSize) {
1835466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                    mSocketBufferSize = maxSystemSocketBufferSize;
1844c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                }
1854c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
1864c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            if (fp) {
1874c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                fclose(fp);
1884c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
1894c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
1909a844cf78f09953145200b4074d47589257a408cAravind Akella            mWakeLockAcquired = false;
19156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            mLooper = new Looper(false);
1928493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
1938493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            mSensorEventBuffer = new sensors_event_t[minBufferSize];
1948493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            mSensorEventScratch = new sensors_event_t[minBufferSize];
1958493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize];
196a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella            mCurrentOperatingMode = NORMAL;
1977830ef3dd0ff3749d974c2dd85a8fa59dc47aecaAravind Akella
198b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            mAckReceiver = new SensorEventAckReceiver(this);
199b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
2007b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            mInitCheck = NO_ERROR;
2017830ef3dd0ff3749d974c2dd85a8fa59dc47aecaAravind Akella            run("SensorService", PRIORITY_URGENT_DISPLAY);
2027b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian        }
203fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
204fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
205fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
2060319306670b0344da99efa606b6f172dde575a39Mathias AgopianSensor SensorService::registerSensor(SensorInterface* s)
207f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{
208f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    sensors_event_t event;
209f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    memset(&event, 0, sizeof(event));
210f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
211f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    const Sensor sensor(s->getSensor());
212f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    // add to the sensor list (returned to clients)
213f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    mSensorList.add(sensor);
214f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    // add to our handle->SensorInterface mapping
215f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    mSensorMap.add(sensor.getHandle(), s);
216f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    // create an entry in the mLastEventSeen array
217f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    mLastEventSeen.add(sensor.getHandle(), event);
2180319306670b0344da99efa606b6f172dde575a39Mathias Agopian
2190319306670b0344da99efa606b6f172dde575a39Mathias Agopian    return sensor;
220f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
221f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
2220319306670b0344da99efa606b6f172dde575a39Mathias AgopianSensor SensorService::registerVirtualSensor(SensorInterface* s)
223f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{
2240319306670b0344da99efa606b6f172dde575a39Mathias Agopian    Sensor sensor = registerSensor(s);
225f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    mVirtualSensorList.add( s );
2260319306670b0344da99efa606b6f172dde575a39Mathias Agopian    return sensor;
227f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
228f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
229fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::~SensorService()
230fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
231f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    for (size_t i=0 ; i<mSensorMap.size() ; i++)
232f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        delete mSensorMap.valueAt(i);
233fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
234fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
2354949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akellastatus_t SensorService::dump(int fd, const Vector<String16>& args)
236fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
237fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    String8 result;
2381cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
239ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian        result.appendFormat("Permission Denial: "
240700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                "can't dump SensorService from pid=%d, uid=%d\n",
241fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian                IPCThreadState::self()->getCallingPid(),
242fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian                IPCThreadState::self()->getCallingUid());
2434949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    } else if (args.size() > 0) {
2444949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        if (args.size() > 1) {
2454949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella           return INVALID_OPERATION;
2464949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        }
2474949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        Mutex::Autolock _l(mLock);
2484949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        SensorDevice& dev(SensorDevice::getInstance());
249a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        if (args[0] == String16("restrict") && mCurrentOperatingMode == NORMAL) {
250a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella            mCurrentOperatingMode = RESTRICTED;
2514949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            dev.disableAllSensors();
2524949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            // Clear all pending flush connections for all active sensors. If one of the active
2534949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            // connections has called flush() and the underlying sensor has been disabled before a
2544949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            // flush complete event is returned, we need to remove the connection from this queue.
2554949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            for (size_t i=0 ; i< mActiveSensors.size(); ++i) {
2564949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella                mActiveSensors.valueAt(i)->clearAllPendingFlushConnections();
2574949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            }
258a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        } else if (args[0] == String16("enable") && mCurrentOperatingMode == RESTRICTED) {
259a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella            mCurrentOperatingMode = NORMAL;
2604949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            dev.enableAllSensors();
2614949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        }
2624949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        return status_t(NO_ERROR);
263fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    } else {
264fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        Mutex::Autolock _l(mLock);
265ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian        result.append("Sensor List:\n");
2663560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        for (size_t i=0 ; i<mSensorList.size() ; i++) {
2673560fb24b668675627934356f210d84d19bf4e56Mathias Agopian            const Sensor& s(mSensorList[i]);
2683560fb24b668675627934356f210d84d19bf4e56Mathias Agopian            const sensors_event_t& e(mLastEventSeen.valueFor(s.getHandle()));
269ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            result.appendFormat(
2700b6acb2231baed861488f2d181621272d0658d25Aravind Akella                    "%-15s| %-10s| version=%d |%-20s| 0x%08x | \"%s\" | type=%d |",
2713560fb24b668675627934356f210d84d19bf4e56Mathias Agopian                    s.getName().string(),
2723560fb24b668675627934356f210d84d19bf4e56Mathias Agopian                    s.getVendor().string(),
2730b6acb2231baed861488f2d181621272d0658d25Aravind Akella                    s.getVersion(),
274700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                    s.getStringType().string(),
275700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                    s.getHandle(),
2766c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                    s.getRequiredPermission().string(),
2776c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                    s.getType());
278ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian
2790e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            const int reportingMode = s.getReportingMode();
2800e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            if (reportingMode == AREPORTING_MODE_CONTINUOUS) {
2816c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                result.append(" continuous | ");
2820e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            } else if (reportingMode == AREPORTING_MODE_ON_CHANGE) {
2836c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                result.append(" on-change | ");
2840e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            } else if (reportingMode == AREPORTING_MODE_ONE_SHOT) {
2856c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                result.append(" one-shot | ");
2860e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            } else {
2876c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                result.append(" special-trigger | ");
2886c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            }
2896c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
2906c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            if (s.getMaxDelay() > 0) {
2916c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                result.appendFormat("minRate=%.2fHz | ", 1e6f / s.getMaxDelay());
2926c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            } else {
2936c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                result.appendFormat("maxDelay=%dus |", s.getMaxDelay());
2940e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            }
2950e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella
296ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            if (s.getMinDelay() > 0) {
2976c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                result.appendFormat("maxRate=%.2fHz | ", 1e6f / s.getMinDelay());
298ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            } else {
2996c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                result.appendFormat("minDelay=%dus |", s.getMinDelay());
300ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            }
3010e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella
302724d91d778e71c8186399f4955de14b54812b3edAravind Akella            if (s.getFifoMaxEventCount() > 0) {
303700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                result.appendFormat("FifoMax=%d events | ",
304700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                        s.getFifoMaxEventCount());
305724d91d778e71c8186399f4955de14b54812b3edAravind Akella            } else {
3066c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                result.append("no batching | ");
3076c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            }
3086c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
3096c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            if (s.isWakeUpSensor()) {
3106c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                result.appendFormat("wakeUp | ");
3116c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            } else {
3126c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                result.appendFormat("non-wakeUp | ");
313724d91d778e71c8186399f4955de14b54812b3edAravind Akella            }
314ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian
315ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            switch (s.getType()) {
316ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_ROTATION_VECTOR:
317ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
318ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    result.appendFormat(
3196c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                            "last=<%5.1f,%5.1f,%5.1f,%5.1f,%5.1f, %" PRId64 ">\n",
3206c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                            e.data[0], e.data[1], e.data[2], e.data[3], e.data[4], e.timestamp);
321ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    break;
322ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
323ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
324ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    result.appendFormat(
3256c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                            "last=<%5.1f,%5.1f,%5.1f,%5.1f,%5.1f,%5.1f, %" PRId64 ">\n",
3266c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                            e.data[0], e.data[1], e.data[2], e.data[3], e.data[4], e.data[5],
3276c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                            e.timestamp);
328ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    break;
329ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_GAME_ROTATION_VECTOR:
330ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    result.appendFormat(
3316c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                            "last=<%5.1f,%5.1f,%5.1f,%5.1f, %" PRId64 ">\n",
3326c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                            e.data[0], e.data[1], e.data[2], e.data[3], e.timestamp);
333ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    break;
334ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_SIGNIFICANT_MOTION:
335ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_STEP_DETECTOR:
3366c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                    result.appendFormat( "last=<%f %" PRId64 ">\n", e.data[0], e.timestamp);
337ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    break;
338ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_STEP_COUNTER:
3396c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                    result.appendFormat( "last=<%" PRIu64 ", %" PRId64 ">\n", e.u64.step_counter,
3406c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                                         e.timestamp);
341ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    break;
342ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                default:
343ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    // default to 3 values
344ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    result.appendFormat(
3456c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                            "last=<%5.1f,%5.1f,%5.1f, %" PRId64 ">\n",
3466c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                            e.data[0], e.data[1], e.data[2], e.timestamp);
347ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    break;
348ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            }
3496c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            result.append("\n");
3503560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        }
351ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian        SensorFusion::getInstance().dump(result);
352ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian        SensorDevice::getInstance().dump(result);
353ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian
354ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian        result.append("Active sensors:\n");
355fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        for (size_t i=0 ; i<mActiveSensors.size() ; i++) {
3565d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian            int handle = mActiveSensors.keyAt(i);
35792dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn            result.appendFormat("%s (handle=0x%08x, connections=%zu)\n",
3585d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian                    getSensorName(handle).string(),
3595d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian                    handle,
360fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian                    mActiveSensors.valueAt(i)->getNumConnections());
361fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
3624c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
3635466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella        result.appendFormat("Socket Buffer size = %d events\n",
3646c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                            mSocketBufferSize/sizeof(sensors_event_t));
3659a844cf78f09953145200b4074d47589257a408cAravind Akella        result.appendFormat("WakeLock Status: %s \n", mWakeLockAcquired ? "acquired" : "not held");
3664949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        result.appendFormat("Mode :");
367a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        switch(mCurrentOperatingMode) {
3684949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella           case NORMAL:
3694949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella               result.appendFormat(" NORMAL\n");
3704949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella               break;
3714949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella           case RESTRICTED:
3724949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella               result.appendFormat(" RESTRICTED\n");
3734949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella               break;
3744949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella           case DATA_INJECTION:
3754949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella               result.appendFormat(" DATA_INJECTION\n");
3764949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        }
37792dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn        result.appendFormat("%zd active connections\n", mActiveConnections.size());
3784c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
3794c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        for (size_t i=0 ; i < mActiveConnections.size() ; i++) {
3804c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            sp<SensorEventConnection> connection(mActiveConnections[i].promote());
3814c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            if (connection != 0) {
38292dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn                result.appendFormat("Connection Number: %zu \n", i);
3834c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                connection->dump(result);
3844c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
3854c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
386fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
387fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    write(fd, result.string(), result.size());
388fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return NO_ERROR;
389fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
390fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
3919a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::cleanupAutoDisabledSensorLocked(const sp<SensorEventConnection>& connection,
3924342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        sensors_event_t const* buffer, const int count) {
3934342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    for (int i=0 ; i<count ; i++) {
3944342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        int handle = buffer[i].sensor;
3958493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        if (buffer[i].type == SENSOR_TYPE_META_DATA) {
3968493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            handle = buffer[i].meta_data.sensor;
3978493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        }
3980e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella        if (connection->hasSensor(handle)) {
3990e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            SensorInterface* sensor = mSensorMap.valueFor(handle);
4000e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            // If this buffer has an event from a one_shot sensor and this connection is registered
4010e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            // for this particular one_shot sensor, try cleaning up the connection.
4020e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            if (sensor != NULL &&
4030e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella                sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
4040e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella                sensor->autoDisable(connection.get(), handle);
4059a844cf78f09953145200b4074d47589257a408cAravind Akella                cleanupWithoutDisableLocked(connection, handle);
4064342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            }
407a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
4084342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
409a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella   }
4104342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh}
4114342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
412fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::threadLoop()
413fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
414a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block    ALOGD("nuSensorService thread starting...");
415fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
41690ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    // each virtual sensor could generate an event per "real" event, that's why we need
41790ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    // to size numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT.
41890ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    // in practice, this is too aggressive, but guaranteed to be enough.
41990ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
42090ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    const size_t numEventMax = minBufferSize / (1 + mVirtualSensorList.size());
42190ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian
422f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    SensorDevice& device(SensorDevice::getInstance());
423f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    const size_t vcount = mVirtualSensorList.size();
424fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
4254342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    const int halVersion = device.getHalDeviceVersion();
426fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    do {
4278493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
4288493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        if (count < 0) {
429f5a1230d322c14c42331d0a1536b50c87742973bSteve Block            ALOGE("sensor poll failed (%s)", strerror(-count));
430fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            break;
431fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
43256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
43356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        // Reset sensors_event_t.flags to zero for all events in the buffer.
43456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        for (int i = 0; i < count; i++) {
4358493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella             mSensorEventBuffer[i].flags = 0;
43656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        }
437e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella
438e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella        // Make a copy of the connection vector as some connections may be removed during the
439e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella        // course of this loop (especially when one-shot sensor events are present in the
440e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella        // sensor_event buffer). Promote all connections to StrongPointers before the lock is
441e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella        // acquired. If the destructor of the sp gets called when the lock is acquired, it may
442e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella        // result in a deadlock as ~SensorEventConnection() needs to acquire mLock again for
443e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella        // cleanup. So copy all the strongPointers to a vector before the lock is acquired.
444e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella        SortedVector< sp<SensorEventConnection> > activeConnections;
445b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        populateActiveConnections(&activeConnections);
4469a844cf78f09953145200b4074d47589257a408cAravind Akella        Mutex::Autolock _l(mLock);
4479a844cf78f09953145200b4074d47589257a408cAravind Akella        // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The
4489a844cf78f09953145200b4074d47589257a408cAravind Akella        // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock,
4499a844cf78f09953145200b4074d47589257a408cAravind Akella        // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should
4509a844cf78f09953145200b4074d47589257a408cAravind Akella        // not be interleaved with decrementing SensorEventConnection::mWakeLockRefCount and
4519a844cf78f09953145200b4074d47589257a408cAravind Akella        // releasing the wakelock.
4529a844cf78f09953145200b4074d47589257a408cAravind Akella        bool bufferHasWakeUpEvent = false;
4534342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        for (int i = 0; i < count; i++) {
4548493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            if (isWakeUpSensorEvent(mSensorEventBuffer[i])) {
4559a844cf78f09953145200b4074d47589257a408cAravind Akella                bufferHasWakeUpEvent = true;
4569a844cf78f09953145200b4074d47589257a408cAravind Akella                break;
4574342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            }
4584342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
4594342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
4609a844cf78f09953145200b4074d47589257a408cAravind Akella        if (bufferHasWakeUpEvent && !mWakeLockAcquired) {
461b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            setWakeLockAcquiredLocked(true);
4629a844cf78f09953145200b4074d47589257a408cAravind Akella        }
4638493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        recordLastValueLocked(mSensorEventBuffer, count);
46494e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian
465f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        // handle virtual sensors
466f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        if (count && vcount) {
4678493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            sensors_event_t const * const event = mSensorEventBuffer;
4689a844cf78f09953145200b4074d47589257a408cAravind Akella            const size_t activeVirtualSensorCount = mActiveVirtualSensors.size();
469f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            if (activeVirtualSensorCount) {
470f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                size_t k = 0;
471984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                SensorFusion& fusion(SensorFusion::getInstance());
472984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                if (fusion.isEnabled()) {
473984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                    for (size_t i=0 ; i<size_t(count) ; i++) {
474984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                        fusion.process(event[i]);
475984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                    }
476984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                }
477d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) {
478f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {
479d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                        if (count + k >= minBufferSize) {
480d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                            ALOGE("buffer too small to hold all events: "
481db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn                                    "count=%zd, k=%zu, size=%zu",
482d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                                    count, k, minBufferSize);
483d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                            break;
484d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                        }
485f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                        sensors_event_t out;
4869a844cf78f09953145200b4074d47589257a408cAravind Akella                        SensorInterface* si = mActiveVirtualSensors.valueAt(j);
487d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                        if (si->process(&out, event[i])) {
4888493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                            mSensorEventBuffer[count + k] = out;
489f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                            k++;
490f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                        }
491f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    }
492f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                }
493f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                if (k) {
494f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    // record the last synthesized values
4958493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    recordLastValueLocked(&mSensorEventBuffer[count], k);
496f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    count += k;
497f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    // sort the buffer by time-stamps
4988493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    sortEventBuffer(mSensorEventBuffer, count);
499f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                }
500f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            }
501f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        }
502f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
5034342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // handle backward compatibility for RotationVector sensor
5044342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) {
5054342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            for (int i = 0; i < count; i++) {
5068493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                if (mSensorEventBuffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) {
5074342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                    // All the 4 components of the quaternion should be available
5084342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                    // No heading accuracy. Set it to -1
5098493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    mSensorEventBuffer[i].data[4] = -1;
5108493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                }
5118493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            }
5128493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        }
5138493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella
5148493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        // Map flush_complete_events in the buffer to SensorEventConnections which called
5158493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        // flush on the hardware sensor. mapFlushEventsToConnections[i] will be the
5168493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        // SensorEventConnection mapped to the corresponding flush_complete_event in
5178493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        // mSensorEventBuffer[i] if such a mapping exists (NULL otherwise).
5188493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        for (int i = 0; i < count; ++i) {
5198493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            mMapFlushEventsToConnections[i] = NULL;
5208493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            if (mSensorEventBuffer[i].type == SENSOR_TYPE_META_DATA) {
5218493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                const int sensor_handle = mSensorEventBuffer[i].meta_data.sensor;
5228493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                SensorRecord* rec = mActiveSensors.valueFor(sensor_handle);
5238493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                if (rec != NULL) {
5248493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    mMapFlushEventsToConnections[i] = rec->getFirstPendingFlushConnection();
5258493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    rec->removeFirstPendingFlushConnection();
5264342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                }
5274342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            }
5284342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
5294342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
5309a844cf78f09953145200b4074d47589257a408cAravind Akella        // Send our events to clients. Check the state of wake lock for each client and release the
5319a844cf78f09953145200b4074d47589257a408cAravind Akella        // lock if none of the clients need it.
5329a844cf78f09953145200b4074d47589257a408cAravind Akella        bool needsWakeLock = false;
5338493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        size_t numConnections = activeConnections.size();
5348493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        for (size_t i=0 ; i < numConnections; ++i) {
535e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella            if (activeConnections[i] != 0) {
536e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella                activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,
5378493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                        mMapFlushEventsToConnections);
538e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella                needsWakeLock |= activeConnections[i]->needsWakeLock();
5398493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                // If the connection has one-shot sensors, it may be cleaned up after first trigger.
5408493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                // Early check for one-shot sensors.
541e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella                if (activeConnections[i]->hasOneShotSensors()) {
542e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella                    cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer,
543e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella                            count);
5448493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                }
545fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            }
546fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
5474342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
5489a844cf78f09953145200b4074d47589257a408cAravind Akella        if (mWakeLockAcquired && !needsWakeLock) {
549b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            setWakeLockAcquiredLocked(false);
5509a844cf78f09953145200b4074d47589257a408cAravind Akella        }
5518493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella    } while (!Thread::exitPending());
552fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
5533c20fbed7f3a916ced10f2ed5a272271b7d81edeSteve Block    ALOGW("Exiting SensorService::threadLoop => aborting...");
5541a62301fc58cd2af18239b0415813461bf5fc41bMathias Agopian    abort();
555fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return false;
556fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
557fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
55856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellasp<Looper> SensorService::getLooper() const {
55956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    return mLooper;
56056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella}
56156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
562b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::resetAllWakeLockRefCounts() {
563b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    SortedVector< sp<SensorEventConnection> > activeConnections;
564b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    populateActiveConnections(&activeConnections);
565b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    {
566b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        Mutex::Autolock _l(mLock);
567b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        for (size_t i=0 ; i < activeConnections.size(); ++i) {
568b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            if (activeConnections[i] != 0) {
569b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella                activeConnections[i]->resetWakeLockRefCount();
570b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            }
571b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        }
572b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        setWakeLockAcquiredLocked(false);
573b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    }
574b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
575b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
576b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::setWakeLockAcquiredLocked(bool acquire) {
577b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    if (acquire) {
578b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        if (!mWakeLockAcquired) {
579b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
580b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            mWakeLockAcquired = true;
581b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        }
582b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        mLooper->wake();
583b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    } else {
584b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        if (mWakeLockAcquired) {
585b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            release_wake_lock(WAKE_LOCK_NAME);
586b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            mWakeLockAcquired = false;
587b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        }
588b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    }
589b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
590b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
591b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellabool SensorService::isWakeLockAcquired() {
592b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    Mutex::Autolock _l(mLock);
593b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    return mWakeLockAcquired;
594b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
595b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
59656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellabool SensorService::SensorEventAckReceiver::threadLoop() {
59756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    ALOGD("new thread SensorEventAckReceiver");
598b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    sp<Looper> looper = mService->getLooper();
59956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    do {
600b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        bool wakeLockAcquired = mService->isWakeLockAcquired();
601b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        int timeout = -1;
602b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        if (wakeLockAcquired) timeout = 5000;
603b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        int ret = looper->pollOnce(timeout);
604b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        if (ret == ALOOPER_POLL_TIMEOUT) {
605b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella           mService->resetAllWakeLockRefCounts();
606b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        }
60756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    } while(!Thread::exitPending());
60856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    return false;
60956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella}
61056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
6119a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::recordLastValueLocked(
6124b84704b97300eff3ebfab85652e64d54149d205Aravind Akella        const sensors_event_t* buffer, size_t count) {
6134b84704b97300eff3ebfab85652e64d54149d205Aravind Akella    const sensors_event_t* last = NULL;
6144b84704b97300eff3ebfab85652e64d54149d205Aravind Akella    for (size_t i = 0; i < count; i++) {
6154b84704b97300eff3ebfab85652e64d54149d205Aravind Akella        const sensors_event_t* event = &buffer[i];
6164b84704b97300eff3ebfab85652e64d54149d205Aravind Akella        if (event->type != SENSOR_TYPE_META_DATA) {
6174b84704b97300eff3ebfab85652e64d54149d205Aravind Akella            if (last && event->sensor != last->sensor) {
6184b84704b97300eff3ebfab85652e64d54149d205Aravind Akella                mLastEventSeen.editValueFor(last->sensor) = *last;
6194b84704b97300eff3ebfab85652e64d54149d205Aravind Akella            }
6204b84704b97300eff3ebfab85652e64d54149d205Aravind Akella            last = event;
62194e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian        }
62294e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian    }
6234b84704b97300eff3ebfab85652e64d54149d205Aravind Akella    if (last) {
6244b84704b97300eff3ebfab85652e64d54149d205Aravind Akella        mLastEventSeen.editValueFor(last->sensor) = *last;
6254b84704b97300eff3ebfab85652e64d54149d205Aravind Akella    }
62694e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian}
62794e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian
628f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopianvoid SensorService::sortEventBuffer(sensors_event_t* buffer, size_t count)
629f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{
630f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    struct compar {
631f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        static int cmp(void const* lhs, void const* rhs) {
632f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            sensors_event_t const* l = static_cast<sensors_event_t const*>(lhs);
633f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            sensors_event_t const* r = static_cast<sensors_event_t const*>(rhs);
634a5c106a4f0afcf061728a1cb7c8c3b908728575dMathias Agopian            return l->timestamp - r->timestamp;
635f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        }
636f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    };
637f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    qsort(buffer, count, sizeof(sensors_event_t), compar::cmp);
638f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
639f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
6405d2707214dfb97bd8dfcc6620be36841d3c82420Mathias AgopianString8 SensorService::getSensorName(int handle) const {
641010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian    size_t count = mUserSensorList.size();
6425d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
643010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian        const Sensor& sensor(mUserSensorList[i]);
6445d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian        if (sensor.getHandle() == handle) {
6455d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian            return sensor.getName();
6465d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian        }
6475d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian    }
6485d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian    String8 result("unknown");
6495d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian    return result;
6505d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian}
6515d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian
652b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akellabool SensorService::isVirtualSensor(int handle) const {
653b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella    SensorInterface* sensor = mSensorMap.valueFor(handle);
654b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella    return sensor->isVirtual();
655b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella}
656b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella
6579a844cf78f09953145200b4074d47589257a408cAravind Akellabool SensorService::isWakeUpSensorEvent(const sensors_event_t& event) const {
6587869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan    int handle = event.sensor;
6597869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan    if (event.type == SENSOR_TYPE_META_DATA) {
6607869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan        handle = event.meta_data.sensor;
6617869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan    }
6627869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan    SensorInterface* sensor = mSensorMap.valueFor(handle);
6637869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan    return sensor != NULL && sensor->getSensor().isWakeUpSensor();
6649a844cf78f09953145200b4074d47589257a408cAravind Akella}
6659a844cf78f09953145200b4074d47589257a408cAravind Akella
6666c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind AkellaSensorService::SensorRecord * SensorService::getSensorRecord(int handle) {
6676c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella     return mActiveSensors.valueFor(handle);
6686c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella}
6696c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
670b412f6e203b38f8047f760261a5e3dc6d0722f08SvetoslavVector<Sensor> SensorService::getSensorList(const String16& opPackageName)
671fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
67233264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian    char value[PROPERTY_VALUE_MAX];
67333264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian    property_get("debug.sensors", value, "0");
674700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    const Vector<Sensor>& initialSensorList = (atoi(value)) ?
675700180487ffec09d9df1657b018a7caadac24b75Aravind Akella            mUserSensorListDebug : mUserSensorList;
676700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    Vector<Sensor> accessibleSensorList;
677700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    for (size_t i = 0; i < initialSensorList.size(); i++) {
678700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        Sensor sensor = initialSensorList[i];
679b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        if (canAccessSensor(sensor, "getSensorList", opPackageName)) {
680700180487ffec09d9df1657b018a7caadac24b75Aravind Akella            accessibleSensorList.add(sensor);
681700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        } else {
682b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            ALOGI("Skipped sensor %s because it requires permission %s and app op %d",
6835f6199373dc1e07d2ee5edbae7ecfa08a065492eBernhard Rosenkränzer                  sensor.getName().string(),
684b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                  sensor.getRequiredPermission().string(),
685b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                  sensor.getRequiredAppOp());
686700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        }
68733264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian    }
688700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    return accessibleSensorList;
689fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
690fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
691a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellasp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName,
692b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        int requestedMode, const String16& opPackageName) {
693a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    // Only 2 modes supported for a SensorEventConnection ... NORMAL and DATA_INJECTION.
694a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    if (requestedMode != NORMAL && requestedMode != DATA_INJECTION) {
695a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        return NULL;
696a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    }
697a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    // DATA_INJECTION mode needs to have the required permissions set.
698a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    if (requestedMode == DATA_INJECTION && !hasDataInjectionPermissions()) {
699a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        return NULL;
700a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    }
701a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
702a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    Mutex::Autolock _l(mLock);
7035307d17fe33fc26eeeacd6339a9fbfe96cf56873Mathias Agopian    uid_t uid = IPCThreadState::self()->getCallingUid();
704a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    sp<SensorEventConnection> result(new SensorEventConnection(this, uid, packageName,
705b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            requestedMode == DATA_INJECTION, opPackageName));
706a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    if (requestedMode == DATA_INJECTION) {
707a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        if (mActiveConnections.indexOf(result) < 0) {
708a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella            mActiveConnections.add(result);
709a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        }
710a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        // Add the associated file descriptor to the Looper for polling whenever there is data to
711a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        // be injected.
712a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        result->updateLooperRegistration(mLooper);
713a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    }
714fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return result;
715fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
716fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
717a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatus_t SensorService::enableDataInjection(int requestedMode) {
718a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    if (!hasDataInjectionPermissions()) {
719a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        return INVALID_OPERATION;
720a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    }
721a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    Mutex::Autolock _l(mLock);
722a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    ALOGD_IF(DEBUG_CONNECTIONS, "SensorService::enableDataInjection %d", requestedMode);
723a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    SensorDevice& dev(SensorDevice::getInstance());
724a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    status_t err(NO_ERROR);
725a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    if (requestedMode == DATA_INJECTION) {
726a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        if (mCurrentOperatingMode == NORMAL) {
727a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella           dev.disableAllSensors();
728a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella           err = dev.setMode(requestedMode);
729a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella           if (err == NO_ERROR) {
730a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               mCurrentOperatingMode = DATA_INJECTION;
731a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella           } else {
732a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               // Re-enable sensors.
733a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               dev.enableAllSensors();
734a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella           }
735a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella       } else if (mCurrentOperatingMode == DATA_INJECTION) {
736a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella           // Already in DATA_INJECTION mode. Treat this as a no_op.
737a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella           return NO_ERROR;
738a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella       } else {
739a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella           // Transition to data injection mode supported only from NORMAL mode.
740a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella           return INVALID_OPERATION;
741a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella       }
742a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    } else if (requestedMode == NORMAL && mCurrentOperatingMode != NORMAL) {
743a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella       err = resetToNormalModeLocked();
744a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    }
745a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    return err;
746a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella}
747a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
748a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatus_t SensorService::resetToNormalMode() {
749a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    Mutex::Autolock _l(mLock);
750a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    return resetToNormalModeLocked();
751a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella}
752a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
753a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatus_t SensorService::resetToNormalModeLocked() {
754a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    SensorDevice& dev(SensorDevice::getInstance());
755a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    dev.enableAllSensors();
756a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    status_t err = dev.setMode(NORMAL);
757a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    mCurrentOperatingMode = NORMAL;
758a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    return err;
759a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella}
760a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
761db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopianvoid SensorService::cleanupConnection(SensorEventConnection* c)
762fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
763fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    Mutex::Autolock _l(mLock);
764db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian    const wp<SensorEventConnection> connection(c);
7657c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    size_t size = mActiveSensors.size();
766db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn    ALOGD_IF(DEBUG_CONNECTIONS, "%zu active sensors", size);
7677c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    for (size_t i=0 ; i<size ; ) {
768db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        int handle = mActiveSensors.keyAt(i);
769db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        if (c->hasSensor(handle)) {
770db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn            ALOGD_IF(DEBUG_CONNECTIONS, "%zu: disabling handle=0x%08x", i, handle);
771f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            SensorInterface* sensor = mSensorMap.valueFor( handle );
772f5a1230d322c14c42331d0a1536b50c87742973bSteve Block            ALOGE_IF(!sensor, "mSensorMap[handle=0x%08x] is null!", handle);
773f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            if (sensor) {
774db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian                sensor->activate(c, false);
775f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            }
7768a96955c8e14db40b16164236830fc9506a00872Aravind Akella            c->removeSensor(handle);
777db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        }
778db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        SensorRecord* rec = mActiveSensors.valueAt(i);
779db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn        ALOGE_IF(!rec, "mActiveSensors[%zu] is null (handle=0x%08x)!", i, handle);
780a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block        ALOGD_IF(DEBUG_CONNECTIONS,
781db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn                "removing connection %p for sensor[%zu].handle=0x%08x",
782a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian                c, i, handle);
783a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian
784db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        if (rec && rec->removeConnection(connection)) {
785a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block            ALOGD_IF(DEBUG_CONNECTIONS, "... and it was the last connection");
7867c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            mActiveSensors.removeItemsAt(i, 1);
787f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            mActiveVirtualSensors.removeItem(handle);
7887c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            delete rec;
7897c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            size--;
7907c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian        } else {
7917c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            i++;
792fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
793fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
7948a96955c8e14db40b16164236830fc9506a00872Aravind Akella    c->updateLooperRegistration(mLooper);
7957c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    mActiveConnections.remove(connection);
796787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian    BatteryService::cleanup(c->getUid());
7979a844cf78f09953145200b4074d47589257a408cAravind Akella    if (c->needsWakeLock()) {
7989a844cf78f09953145200b4074d47589257a408cAravind Akella        checkWakeLockStateLocked();
7999a844cf78f09953145200b4074d47589257a408cAravind Akella    }
800fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
801fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
802700180487ffec09d9df1657b018a7caadac24b75Aravind AkellaSensor SensorService::getSensorFromHandle(int handle) const {
803700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    return mSensorMap.valueFor(handle)->getSensor();
804700180487ffec09d9df1657b018a7caadac24b75Aravind Akella}
805700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
806fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::enable(const sp<SensorEventConnection>& connection,
807b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags,
808b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        const String16& opPackageName)
809fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
81050df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian    if (mInitCheck != NO_ERROR)
81150df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian        return mInitCheck;
81250df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
813f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    SensorInterface* sensor = mSensorMap.valueFor(handle);
814ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    if (sensor == NULL) {
815ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        return BAD_VALUE;
816ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    }
817700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
818b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (!canAccessSensor(sensor->getSensor(), "Tried enabling", opPackageName)) {
819700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return BAD_VALUE;
820700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
821700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
822ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    Mutex::Autolock _l(mLock);
823a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    if (mCurrentOperatingMode == RESTRICTED && !isWhiteListedPackage(connection->getPackageName())) {
8244949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        return INVALID_OPERATION;
8254949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    }
8264949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
8274342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    SensorRecord* rec = mActiveSensors.valueFor(handle);
8284342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (rec == 0) {
8294342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        rec = new SensorRecord(connection);
8304342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        mActiveSensors.add(handle, rec);
8314342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (sensor->isVirtual()) {
8324342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            mActiveVirtualSensors.add(handle, sensor);
8333560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        }
8344342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    } else {
8354342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (rec->addConnection(connection)) {
8369a844cf78f09953145200b4074d47589257a408cAravind Akella            // this sensor is already activated, but we are adding a connection that uses it.
8379a844cf78f09953145200b4074d47589257a408cAravind Akella            // Immediately send down the last known value of the requested sensor if it's not a
8384342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            // "continuous" sensor.
8390e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ON_CHANGE) {
8409a844cf78f09953145200b4074d47589257a408cAravind Akella                // NOTE: The wake_up flag of this event may get set to
8419a844cf78f09953145200b4074d47589257a408cAravind Akella                // WAKE_UP_SENSOR_EVENT_NEEDS_ACK if this is a wake_up event.
8424342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                sensors_event_t& event(mLastEventSeen.editValueFor(handle));
8434342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                if (event.version == sizeof(sensors_event_t)) {
8449a844cf78f09953145200b4074d47589257a408cAravind Akella                    if (isWakeUpSensorEvent(event) && !mWakeLockAcquired) {
845b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella                        setWakeLockAcquiredLocked(true);
8469a844cf78f09953145200b4074d47589257a408cAravind Akella                    }
8479a844cf78f09953145200b4074d47589257a408cAravind Akella                    connection->sendEvents(&event, 1, NULL);
8489a844cf78f09953145200b4074d47589257a408cAravind Akella                    if (!connection->needsWakeLock() && mWakeLockAcquired) {
8499a844cf78f09953145200b4074d47589257a408cAravind Akella                        checkWakeLockStateLocked();
8509a844cf78f09953145200b4074d47589257a408cAravind Akella                    }
851f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                }
8527c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            }
853fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
854fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
8554342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
8564342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (connection->addSensor(handle)) {
8574342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        BatteryService::enableSensor(connection->getUid(), handle);
8584342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // the sensor was added (which means it wasn't already there)
8594342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // so, see if this connection becomes active
8604342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (mActiveConnections.indexOf(connection) < 0) {
8614342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            mActiveConnections.add(connection);
8624342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
8634342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    } else {
8644342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        ALOGW("sensor %08x already enabled in connection %p (ignoring)",
8654342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            handle, connection.get());
8664342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
8674342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
868724d91d778e71c8186399f4955de14b54812b3edAravind Akella    nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
869724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (samplingPeriodNs < minDelayNs) {
870724d91d778e71c8186399f4955de14b54812b3edAravind Akella        samplingPeriodNs = minDelayNs;
871724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
872724d91d778e71c8186399f4955de14b54812b3edAravind Akella
8736c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d"
8746c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                                "rate=%" PRId64 " timeout== %" PRId64"",
875724d91d778e71c8186399f4955de14b54812b3edAravind Akella             handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs);
876724d91d778e71c8186399f4955de14b54812b3edAravind Akella
8774949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    status_t err = sensor->batch(connection.get(), handle, 0, samplingPeriodNs,
878724d91d778e71c8186399f4955de14b54812b3edAravind Akella                                 maxBatchReportLatencyNs);
8796c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
8805466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella    // Call flush() before calling activate() on the sensor. Wait for a first flush complete
8815466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella    // event before sending events on this connection. Ignore one-shot sensors which don't
8825466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella    // support flush(). Also if this sensor isn't already active, don't call flush().
8835466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella    if (err == NO_ERROR && sensor->getSensor().getReportingMode() != AREPORTING_MODE_ONE_SHOT &&
8845466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            rec->getNumConnections() > 1) {
8855466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella        connection->setFirstFlushPending(handle, true);
8864c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        status_t err_flush = sensor->flush(connection.get(), handle);
8875466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella        // Flush may return error if the underlying h/w sensor uses an older HAL.
8886c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        if (err_flush == NO_ERROR) {
8896c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            rec->addPendingFlushConnection(connection.get());
8905466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella        } else {
8915466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            connection->setFirstFlushPending(handle, false);
8924c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
8934c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
894724d91d778e71c8186399f4955de14b54812b3edAravind Akella
895724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (err == NO_ERROR) {
896724d91d778e71c8186399f4955de14b54812b3edAravind Akella        ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle);
897724d91d778e71c8186399f4955de14b54812b3edAravind Akella        err = sensor->activate(connection.get(), true);
898724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
899724d91d778e71c8186399f4955de14b54812b3edAravind Akella
9008a96955c8e14db40b16164236830fc9506a00872Aravind Akella    if (err == NO_ERROR) {
9018a96955c8e14db40b16164236830fc9506a00872Aravind Akella        connection->updateLooperRegistration(mLooper);
90256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    }
90356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
9044342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (err != NO_ERROR) {
905724d91d778e71c8186399f4955de14b54812b3edAravind Akella        // batch/activate has failed, reset our state.
906ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        cleanupWithoutDisableLocked(connection, handle);
9074342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
908fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return err;
909fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
910fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
911fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::disable(const sp<SensorEventConnection>& connection,
912fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        int handle)
913fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
91450df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian    if (mInitCheck != NO_ERROR)
91550df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian        return mInitCheck;
91650df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
917ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    Mutex::Autolock _l(mLock);
918ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    status_t err = cleanupWithoutDisableLocked(connection, handle);
9194342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (err == NO_ERROR) {
9204342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        SensorInterface* sensor = mSensorMap.valueFor(handle);
9214342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        err = sensor ? sensor->activate(connection.get(), false) : status_t(BAD_VALUE);
9224342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
9234342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    return err;
9244342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh}
9254342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
926ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisable(
927ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        const sp<SensorEventConnection>& connection, int handle) {
928fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    Mutex::Autolock _l(mLock);
929ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    return cleanupWithoutDisableLocked(connection, handle);
930ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian}
931ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian
932ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisableLocked(
933ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        const sp<SensorEventConnection>& connection, int handle) {
934fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    SensorRecord* rec = mActiveSensors.valueFor(handle);
935fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (rec) {
936fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        // see if this connection becomes inactive
937787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian        if (connection->removeSensor(handle)) {
938787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian            BatteryService::disableSensor(connection->getUid(), handle);
939787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian        }
940fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        if (connection->hasAnySensor() == false) {
9418a96955c8e14db40b16164236830fc9506a00872Aravind Akella            connection->updateLooperRegistration(mLooper);
942fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            mActiveConnections.remove(connection);
943fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
944fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        // see if this sensor becomes inactive
945fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        if (rec->removeConnection(connection)) {
946fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            mActiveSensors.removeItem(handle);
947f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            mActiveVirtualSensors.removeItem(handle);
948fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            delete rec;
949fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
9504342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        return NO_ERROR;
9517c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    }
9524342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    return BAD_VALUE;
953fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
954fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
9557c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianstatus_t SensorService::setEventRate(const sp<SensorEventConnection>& connection,
956b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        int handle, nsecs_t ns, const String16& opPackageName)
957fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
95850df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian    if (mInitCheck != NO_ERROR)
95950df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian        return mInitCheck;
96050df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
961ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian    SensorInterface* sensor = mSensorMap.valueFor(handle);
962ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian    if (!sensor)
963ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian        return BAD_VALUE;
964ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian
965b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (!canAccessSensor(sensor->getSensor(), "Tried configuring", opPackageName)) {
966700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return BAD_VALUE;
967700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
968700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
9691cd700015318727d6d42236ab6274f1949fb08baMathias Agopian    if (ns < 0)
9701cd700015318727d6d42236ab6274f1949fb08baMathias Agopian        return BAD_VALUE;
9711cd700015318727d6d42236ab6274f1949fb08baMathias Agopian
97262569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian    nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
97362569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian    if (ns < minDelayNs) {
97462569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian        ns = minDelayNs;
975ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian    }
976ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian
977f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    return sensor->setDelay(connection.get(), handle, ns);
978fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
979fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
980b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslavstatus_t SensorService::flushSensor(const sp<SensorEventConnection>& connection,
981b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        const String16& opPackageName) {
982700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    if (mInitCheck != NO_ERROR) return mInitCheck;
9839e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    SensorDevice& dev(SensorDevice::getInstance());
9849e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    const int halVersion = dev.getHalDeviceVersion();
9859e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    status_t err(NO_ERROR);
9869e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    Mutex::Autolock _l(mLock);
9879e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    // Loop through all sensors for this connection and call flush on each of them.
9889e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    for (size_t i = 0; i < connection->mSensorInfo.size(); ++i) {
9899e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        const int handle = connection->mSensorInfo.keyAt(i);
9909e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        SensorInterface* sensor = mSensorMap.valueFor(handle);
9919e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
9929e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            ALOGE("flush called on a one-shot sensor");
9939e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            err = INVALID_OPERATION;
9949e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            continue;
9959e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        }
9968493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        if (halVersion <= SENSORS_DEVICE_API_VERSION_1_0 || isVirtualSensor(handle)) {
9979e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            // For older devices just increment pending flush count which will send a trivial
9989e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            // flush complete event.
9998a96955c8e14db40b16164236830fc9506a00872Aravind Akella            connection->incrementPendingFlushCount(handle);
10009e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        } else {
1001b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            if (!canAccessSensor(sensor->getSensor(), "Tried flushing", opPackageName)) {
1002b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                err = INVALID_OPERATION;
1003b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                continue;
1004b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            }
10059e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            status_t err_flush = sensor->flush(connection.get(), handle);
10069e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            if (err_flush == NO_ERROR) {
10079e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella                SensorRecord* rec = mActiveSensors.valueFor(handle);
10089e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella                if (rec != NULL) rec->addPendingFlushConnection(connection);
10099e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            }
10109e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            err = (err_flush != NO_ERROR) ? err_flush : err;
10119e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        }
10126c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    }
10139e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    return err;
1014700180487ffec09d9df1657b018a7caadac24b75Aravind Akella}
1015700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
1016b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslavbool SensorService::canAccessSensor(const Sensor& sensor, const char* operation,
1017b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        const String16& opPackageName) {
1018b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    const String8& requiredPermission = sensor.getRequiredPermission();
1019700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
1020b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (requiredPermission.length() <= 0) {
1021700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return true;
1022b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    }
1023b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav
1024b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    bool hasPermission = false;
1025b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav
1026b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    // Runtime permissions can't use the cache as they may change.
1027b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (sensor.isRequiredPermissionRuntime()) {
1028b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        hasPermission = checkPermission(String16(requiredPermission),
1029b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                IPCThreadState::self()->getCallingPid(), IPCThreadState::self()->getCallingUid());
1030700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    } else {
1031b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        hasPermission = PermissionCache::checkCallingPermission(String16(requiredPermission));
1032b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    }
1033b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav
1034b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (!hasPermission) {
1035b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        ALOGE("%s a sensor (%s) without holding its required permission: %s",
1036b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                operation, sensor.getName().string(), sensor.getRequiredPermission().string());
1037700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return false;
1038700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
1039b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav
1040b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    const int32_t opCode = sensor.getRequiredAppOp();
1041b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (opCode >= 0) {
1042b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        AppOpsManager appOps;
1043b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        if (appOps.noteOp(opCode, IPCThreadState::self()->getCallingUid(), opPackageName)
1044b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                        != AppOpsManager::MODE_ALLOWED) {
1045b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            ALOGE("%s a sensor (%s) without enabled required app op: %D",
1046b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                    operation, sensor.getName().string(), opCode);
1047b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            return false;
1048b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        }
1049b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    }
1050b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav
1051b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    return true;
1052700180487ffec09d9df1657b018a7caadac24b75Aravind Akella}
1053700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
1054a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellabool SensorService::hasDataInjectionPermissions() {
1055a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    if (!PermissionCache::checkCallingPermission(sDataInjectionPermission)) {
1056a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        ALOGE("Permission Denial trying to activate data injection without"
1057a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella              " the required permission");
1058a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        return false;
1059a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    }
1060a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    return true;
1061a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella}
1062a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
10639a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockState() {
10649a844cf78f09953145200b4074d47589257a408cAravind Akella    Mutex::Autolock _l(mLock);
10659a844cf78f09953145200b4074d47589257a408cAravind Akella    checkWakeLockStateLocked();
10669a844cf78f09953145200b4074d47589257a408cAravind Akella}
10679a844cf78f09953145200b4074d47589257a408cAravind Akella
10689a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockStateLocked() {
10699a844cf78f09953145200b4074d47589257a408cAravind Akella    if (!mWakeLockAcquired) {
10709a844cf78f09953145200b4074d47589257a408cAravind Akella        return;
10719a844cf78f09953145200b4074d47589257a408cAravind Akella    }
10729a844cf78f09953145200b4074d47589257a408cAravind Akella    bool releaseLock = true;
10739a844cf78f09953145200b4074d47589257a408cAravind Akella    for (size_t i=0 ; i<mActiveConnections.size() ; i++) {
10749a844cf78f09953145200b4074d47589257a408cAravind Akella        sp<SensorEventConnection> connection(mActiveConnections[i].promote());
10759a844cf78f09953145200b4074d47589257a408cAravind Akella        if (connection != 0) {
10769a844cf78f09953145200b4074d47589257a408cAravind Akella            if (connection->needsWakeLock()) {
10779a844cf78f09953145200b4074d47589257a408cAravind Akella                releaseLock = false;
10789a844cf78f09953145200b4074d47589257a408cAravind Akella                break;
10799a844cf78f09953145200b4074d47589257a408cAravind Akella            }
10809a844cf78f09953145200b4074d47589257a408cAravind Akella        }
10819a844cf78f09953145200b4074d47589257a408cAravind Akella    }
10829a844cf78f09953145200b4074d47589257a408cAravind Akella    if (releaseLock) {
1083b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        setWakeLockAcquiredLocked(false);
1084b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    }
1085b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
1086b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
1087b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::sendEventsFromCache(const sp<SensorEventConnection>& connection) {
1088b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    Mutex::Autolock _l(mLock);
1089b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    connection->writeToSocketFromCache();
1090b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    if (connection->needsWakeLock()) {
1091b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        setWakeLockAcquiredLocked(true);
1092b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    }
1093b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
1094b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
1095b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::populateActiveConnections(
1096b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        SortedVector< sp<SensorEventConnection> >* activeConnections) {
1097b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    Mutex::Autolock _l(mLock);
1098b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    for (size_t i=0 ; i < mActiveConnections.size(); ++i) {
1099b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        sp<SensorEventConnection> connection(mActiveConnections[i].promote());
1100b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        if (connection != 0) {
1101b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            activeConnections->add(connection);
1102b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        }
11039a844cf78f09953145200b4074d47589257a408cAravind Akella    }
11049a844cf78f09953145200b4074d47589257a408cAravind Akella}
11056c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
11064949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akellabool SensorService::isWhiteListedPackage(const String8& packageName) {
11074949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    // TODO: Come up with a list of packages.
11084949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    return (packageName.find(".cts.") != -1);
11094949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella}
11104949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
1111fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// ---------------------------------------------------------------------------
1112fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorRecord::SensorRecord(
1113fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        const sp<SensorEventConnection>& connection)
1114fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
1115fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    mConnections.add(connection);
1116fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1117fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
11187c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianbool SensorService::SensorRecord::addConnection(
1119fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        const sp<SensorEventConnection>& connection)
1120fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
1121fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (mConnections.indexOf(connection) < 0) {
1122fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        mConnections.add(connection);
11237c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian        return true;
1124fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
11257c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    return false;
1126fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1127fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1128fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::SensorRecord::removeConnection(
1129fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        const wp<SensorEventConnection>& connection)
1130fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
1131fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    ssize_t index = mConnections.indexOf(connection);
1132fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (index >= 0) {
1133fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        mConnections.removeItemsAt(index, 1);
1134fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
11356c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    // Remove this connections from the queue of flush() calls made on this sensor.
11366c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    for (Vector< wp<SensorEventConnection> >::iterator it =
11376c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            mPendingFlushConnections.begin(); it != mPendingFlushConnections.end();) {
11388a96955c8e14db40b16164236830fc9506a00872Aravind Akella
11396c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        if (it->unsafe_get() == connection.unsafe_get()) {
11406c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            it = mPendingFlushConnections.erase(it);
11416c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        } else {
11426c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            ++it;
11436c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        }
11446c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    }
1145fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return mConnections.size() ? false : true;
1146fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1147fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
11486c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akellavoid SensorService::SensorRecord::addPendingFlushConnection(
11496c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        const sp<SensorEventConnection>& connection) {
11506c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    mPendingFlushConnections.add(connection);
11516c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella}
11526c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
11536c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akellavoid SensorService::SensorRecord::removeFirstPendingFlushConnection() {
11546c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    if (mPendingFlushConnections.size() > 0) {
11556c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        mPendingFlushConnections.removeAt(0);
11566c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    }
11576c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella}
11586c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
11596c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind AkellaSensorService::SensorEventConnection *
11606c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind AkellaSensorService::SensorRecord::getFirstPendingFlushConnection() {
11616c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella   if (mPendingFlushConnections.size() > 0) {
11626c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        return mPendingFlushConnections[0].unsafe_get();
11636c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    }
11646c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    return NULL;
11656c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella}
11666c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
11674949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akellavoid SensorService::SensorRecord::clearAllPendingFlushConnections() {
11684949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    mPendingFlushConnections.clear();
11694949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella}
11704949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
1171fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// ---------------------------------------------------------------------------
1172fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1173fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorEventConnection::SensorEventConnection(
1174b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        const sp<SensorService>& service, uid_t uid, String8 packageName, bool isDataInjectionMode,
1175b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        const String16& opPackageName)
11768a96955c8e14db40b16164236830fc9506a00872Aravind Akella    : mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false),
1177b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav      mDead(false), mDataInjectionMode(isDataInjectionMode), mEventCache(NULL),
1178b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav      mCacheSize(0), mMaxCacheSize(0), mPackageName(packageName), mOpPackageName(opPackageName) {
11795466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella    mChannel = new BitTube(mService->mSocketBufferSize);
118056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#if DEBUG_CONNECTIONS
118156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
1182e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella    mTotalAcksNeeded = mTotalAcksReceived = 0;
118356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#endif
1184fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1185fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
118656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind AkellaSensorService::SensorEventConnection::~SensorEventConnection() {
1187a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block    ALOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this);
1188e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella    mService->cleanupConnection(this);
118956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    if (mEventCache != NULL) {
119056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        delete mEventCache;
119156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    }
1192fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1193fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
119456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellavoid SensorService::SensorEventConnection::onFirstRef() {
119556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    LooperCallback::onFirstRef();
1196fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1197fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
11989a844cf78f09953145200b4074d47589257a408cAravind Akellabool SensorService::SensorEventConnection::needsWakeLock() {
11999a844cf78f09953145200b4074d47589257a408cAravind Akella    Mutex::Autolock _l(mConnectionLock);
12008a96955c8e14db40b16164236830fc9506a00872Aravind Akella    return !mDead && mWakeLockRefCount > 0;
12019a844cf78f09953145200b4074d47589257a408cAravind Akella}
12029a844cf78f09953145200b4074d47589257a408cAravind Akella
1203b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::SensorEventConnection::resetWakeLockRefCount() {
1204b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    Mutex::Autolock _l(mConnectionLock);
1205b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    mWakeLockRefCount = 0;
1206b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
1207b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
12084c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akellavoid SensorService::SensorEventConnection::dump(String8& result) {
12094c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    Mutex::Autolock _l(mConnectionLock);
1210a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    result.appendFormat("Operating Mode: %s\n", mDataInjectionMode ? "DATA_INJECTION" : "NORMAL");
12114949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    result.appendFormat("\t%s | WakeLockRefCount %d | uid %d | cache size %d | max cache size %d\n",
12124949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            mPackageName.string(), mWakeLockRefCount, mUid, mCacheSize, mMaxCacheSize);
12134c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
12144c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        const FlushInfo& flushInfo = mSensorInfo.valueAt(i);
12150ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella        result.appendFormat("\t %s 0x%08x | status: %s | pending flush events %d \n",
12164c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                            mService->getSensorName(mSensorInfo.keyAt(i)).string(),
12176c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                            mSensorInfo.keyAt(i),
12184c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                            flushInfo.mFirstFlushPending ? "First flush pending" :
12194c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                                                           "active",
12200ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella                            flushInfo.mPendingFlushEventsToSend);
12210ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella    }
122256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#if DEBUG_CONNECTIONS
12230ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella    result.appendFormat("\t events recvd: %d | sent %d | cache %d | dropped %d |"
12240ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella            " total_acks_needed %d | total_acks_recvd %d\n",
12250ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella            mEventsReceived,
12260ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella            mEventsSent,
12270ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella            mEventsSentFromCache,
12280ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella            mEventsReceived - (mEventsSentFromCache + mEventsSent + mCacheSize),
12290ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella            mTotalAcksNeeded,
12300ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella            mTotalAcksReceived);
123156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#endif
12324c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella}
12334c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
12347c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianbool SensorService::SensorEventConnection::addSensor(int32_t handle) {
123571d7a5c289c6ef6b5fc86dd4784a075ca6470e38Mathias Agopian    Mutex::Autolock _l(mConnectionLock);
1236b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (!canAccessSensor(mService->getSensorFromHandle(handle),
1237b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            "Tried adding", mOpPackageName)) {
1238700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return false;
1239700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
12404c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    if (mSensorInfo.indexOfKey(handle) < 0) {
12414c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        mSensorInfo.add(handle, FlushInfo());
12427c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian        return true;
1243fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
12447c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    return false;
1245fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1246fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
12477c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianbool SensorService::SensorEventConnection::removeSensor(int32_t handle) {
124871d7a5c289c6ef6b5fc86dd4784a075ca6470e38Mathias Agopian    Mutex::Autolock _l(mConnectionLock);
12494c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    if (mSensorInfo.removeItem(handle) >= 0) {
12507c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian        return true;
12517c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    }
12527c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    return false;
1253fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1254fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1255fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
125671d7a5c289c6ef6b5fc86dd4784a075ca6470e38Mathias Agopian    Mutex::Autolock _l(mConnectionLock);
12574c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    return mSensorInfo.indexOfKey(handle) >= 0;
1258fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1259fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1260fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::SensorEventConnection::hasAnySensor() const {
126171d7a5c289c6ef6b5fc86dd4784a075ca6470e38Mathias Agopian    Mutex::Autolock _l(mConnectionLock);
12627c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    return mSensorInfo.size() ? true : false;
12637c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian}
12647c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian
12658493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akellabool SensorService::SensorEventConnection::hasOneShotSensors() const {
12668493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella    Mutex::Autolock _l(mConnectionLock);
12678493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
12688493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        const int handle = mSensorInfo.keyAt(i);
12698493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        if (mService->getSensorFromHandle(handle).getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
12708493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            return true;
12718493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        }
12728493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella    }
12738493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella    return false;
12748493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella}
12758493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella
12764949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind AkellaString8 SensorService::SensorEventConnection::getPackageName() const {
12774949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    return mPackageName;
12784949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella}
12794949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
12804c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akellavoid SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle,
12814c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                                bool value) {
12824c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    Mutex::Autolock _l(mConnectionLock);
12834c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    ssize_t index = mSensorInfo.indexOfKey(handle);
12844c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    if (index >= 0) {
12854c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
12864c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        flushInfo.mFirstFlushPending = value;
12874c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
12884c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella}
12894c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
12908a96955c8e14db40b16164236830fc9506a00872Aravind Akellavoid SensorService::SensorEventConnection::updateLooperRegistration(const sp<Looper>& looper) {
12918a96955c8e14db40b16164236830fc9506a00872Aravind Akella    Mutex::Autolock _l(mConnectionLock);
12928a96955c8e14db40b16164236830fc9506a00872Aravind Akella    updateLooperRegistrationLocked(looper);
12938a96955c8e14db40b16164236830fc9506a00872Aravind Akella}
12948a96955c8e14db40b16164236830fc9506a00872Aravind Akella
12958a96955c8e14db40b16164236830fc9506a00872Aravind Akellavoid SensorService::SensorEventConnection::updateLooperRegistrationLocked(
12968a96955c8e14db40b16164236830fc9506a00872Aravind Akella        const sp<Looper>& looper) {
1297a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    bool isConnectionActive = (mSensorInfo.size() > 0 && !mDataInjectionMode) ||
1298a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella                              mDataInjectionMode;
12998a96955c8e14db40b16164236830fc9506a00872Aravind Akella    // If all sensors are unregistered OR Looper has encountered an error, we
13008a96955c8e14db40b16164236830fc9506a00872Aravind Akella    // can remove the Fd from the Looper if it has been previously added.
13018a96955c8e14db40b16164236830fc9506a00872Aravind Akella    if (!isConnectionActive || mDead) {
13028a96955c8e14db40b16164236830fc9506a00872Aravind Akella        if (mHasLooperCallbacks) {
13038a96955c8e14db40b16164236830fc9506a00872Aravind Akella            ALOGD_IF(DEBUG_CONNECTIONS, "%p removeFd fd=%d", this, mChannel->getSendFd());
13048a96955c8e14db40b16164236830fc9506a00872Aravind Akella            looper->removeFd(mChannel->getSendFd());
13058a96955c8e14db40b16164236830fc9506a00872Aravind Akella            mHasLooperCallbacks = false;
13068a96955c8e14db40b16164236830fc9506a00872Aravind Akella        }
13078a96955c8e14db40b16164236830fc9506a00872Aravind Akella        return;
13088a96955c8e14db40b16164236830fc9506a00872Aravind Akella    }
13098a96955c8e14db40b16164236830fc9506a00872Aravind Akella
13108a96955c8e14db40b16164236830fc9506a00872Aravind Akella    int looper_flags = 0;
13118a96955c8e14db40b16164236830fc9506a00872Aravind Akella    if (mCacheSize > 0) looper_flags |= ALOOPER_EVENT_OUTPUT;
1312a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    if (mDataInjectionMode) looper_flags |= ALOOPER_EVENT_INPUT;
13138a96955c8e14db40b16164236830fc9506a00872Aravind Akella    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
13148a96955c8e14db40b16164236830fc9506a00872Aravind Akella        const int handle = mSensorInfo.keyAt(i);
13158a96955c8e14db40b16164236830fc9506a00872Aravind Akella        if (mService->getSensorFromHandle(handle).isWakeUpSensor()) {
13168a96955c8e14db40b16164236830fc9506a00872Aravind Akella            looper_flags |= ALOOPER_EVENT_INPUT;
13178a96955c8e14db40b16164236830fc9506a00872Aravind Akella            break;
13188a96955c8e14db40b16164236830fc9506a00872Aravind Akella        }
13198a96955c8e14db40b16164236830fc9506a00872Aravind Akella    }
13208a96955c8e14db40b16164236830fc9506a00872Aravind Akella    // If flags is still set to zero, we don't need to add this fd to the Looper, if
13218a96955c8e14db40b16164236830fc9506a00872Aravind Akella    // the fd has already been added, remove it. This is likely to happen when ALL the
13228a96955c8e14db40b16164236830fc9506a00872Aravind Akella    // events stored in the cache have been sent to the corresponding app.
13238a96955c8e14db40b16164236830fc9506a00872Aravind Akella    if (looper_flags == 0) {
13248a96955c8e14db40b16164236830fc9506a00872Aravind Akella        if (mHasLooperCallbacks) {
13258a96955c8e14db40b16164236830fc9506a00872Aravind Akella            ALOGD_IF(DEBUG_CONNECTIONS, "removeFd fd=%d", mChannel->getSendFd());
13268a96955c8e14db40b16164236830fc9506a00872Aravind Akella            looper->removeFd(mChannel->getSendFd());
13278a96955c8e14db40b16164236830fc9506a00872Aravind Akella            mHasLooperCallbacks = false;
13288a96955c8e14db40b16164236830fc9506a00872Aravind Akella        }
13298a96955c8e14db40b16164236830fc9506a00872Aravind Akella        return;
13308a96955c8e14db40b16164236830fc9506a00872Aravind Akella    }
13318a96955c8e14db40b16164236830fc9506a00872Aravind Akella    // Add the file descriptor to the Looper for receiving acknowledegments if the app has
13328a96955c8e14db40b16164236830fc9506a00872Aravind Akella    // registered for wake-up sensors OR for sending events in the cache.
13338a96955c8e14db40b16164236830fc9506a00872Aravind Akella    int ret = looper->addFd(mChannel->getSendFd(), 0, looper_flags, this, NULL);
13348a96955c8e14db40b16164236830fc9506a00872Aravind Akella    if (ret == 1) {
13358a96955c8e14db40b16164236830fc9506a00872Aravind Akella        ALOGD_IF(DEBUG_CONNECTIONS, "%p addFd fd=%d", this, mChannel->getSendFd());
13368a96955c8e14db40b16164236830fc9506a00872Aravind Akella        mHasLooperCallbacks = true;
13378a96955c8e14db40b16164236830fc9506a00872Aravind Akella    } else {
13388a96955c8e14db40b16164236830fc9506a00872Aravind Akella        ALOGE("Looper::addFd failed ret=%d fd=%d", ret, mChannel->getSendFd());
13398a96955c8e14db40b16164236830fc9506a00872Aravind Akella    }
13408a96955c8e14db40b16164236830fc9506a00872Aravind Akella}
13418a96955c8e14db40b16164236830fc9506a00872Aravind Akella
13428a96955c8e14db40b16164236830fc9506a00872Aravind Akellavoid SensorService::SensorEventConnection::incrementPendingFlushCount(int32_t handle) {
13438a96955c8e14db40b16164236830fc9506a00872Aravind Akella    Mutex::Autolock _l(mConnectionLock);
13448a96955c8e14db40b16164236830fc9506a00872Aravind Akella    ssize_t index = mSensorInfo.indexOfKey(handle);
13458a96955c8e14db40b16164236830fc9506a00872Aravind Akella    if (index >= 0) {
13468a96955c8e14db40b16164236830fc9506a00872Aravind Akella        FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
13478a96955c8e14db40b16164236830fc9506a00872Aravind Akella        flushInfo.mPendingFlushEventsToSend++;
13488a96955c8e14db40b16164236830fc9506a00872Aravind Akella    }
13498a96955c8e14db40b16164236830fc9506a00872Aravind Akella}
13508a96955c8e14db40b16164236830fc9506a00872Aravind Akella
1351fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::SensorEventConnection::sendEvents(
13520ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella        sensors_event_t const* buffer, size_t numEvents,
13538493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        sensors_event_t* scratch,
13548493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        SensorEventConnection const * const * mapFlushEventsToConnections) {
1355cf51001dbf28e9885fcacd4048902f1c75768fe9Mathias Agopian    // filter out events not for this connection
1356b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    int count = 0;
13579a844cf78f09953145200b4074d47589257a408cAravind Akella    Mutex::Autolock _l(mConnectionLock);
13583560fb24b668675627934356f210d84d19bf4e56Mathias Agopian    if (scratch) {
13593560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        size_t i=0;
13603560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        while (i<numEvents) {
13616c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            int32_t sensor_handle = buffer[i].sensor;
1362724d91d778e71c8186399f4955de14b54812b3edAravind Akella            if (buffer[i].type == SENSOR_TYPE_META_DATA) {
1363724d91d778e71c8186399f4955de14b54812b3edAravind Akella                ALOGD_IF(DEBUG_CONNECTIONS, "flush complete event sensor==%d ",
13649e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella                        buffer[i].meta_data.sensor);
13658a96955c8e14db40b16164236830fc9506a00872Aravind Akella                // Setting sensor_handle to the correct sensor to ensure the sensor events per
13668a96955c8e14db40b16164236830fc9506a00872Aravind Akella                // connection are filtered correctly.  buffer[i].sensor is zero for meta_data
13678a96955c8e14db40b16164236830fc9506a00872Aravind Akella                // events.
13686c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                sensor_handle = buffer[i].meta_data.sensor;
1369724d91d778e71c8186399f4955de14b54812b3edAravind Akella            }
13706c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            ssize_t index = mSensorInfo.indexOfKey(sensor_handle);
137156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            // Check if this connection has registered for this sensor. If not continue to the
137256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            // next sensor_event.
137356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            if (index < 0) {
137456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                ++i;
137556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                continue;
13764c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
137756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
137856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
13796c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            // Check if there is a pending flush_complete event for this sensor on this connection.
13808493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            if (buffer[i].type == SENSOR_TYPE_META_DATA && flushInfo.mFirstFlushPending == true &&
13818493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    this == mapFlushEventsToConnections[i]) {
13828493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                flushInfo.mFirstFlushPending = false;
13838493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                ALOGD_IF(DEBUG_CONNECTIONS, "First flush event for sensor==%d ",
13848493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                        buffer[i].meta_data.sensor);
13858493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                ++i;
13868493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                continue;
138756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            }
138856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
138956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            // If there is a pending flush complete event for this sensor on this connection,
139056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            // ignore the event and proceed to the next.
139156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            if (flushInfo.mFirstFlushPending) {
139256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                ++i;
139356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                continue;
13943560fb24b668675627934356f210d84d19bf4e56Mathias Agopian            }
139556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
139656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            do {
13978493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                // Keep copying events into the scratch buffer as long as they are regular
13988493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                // sensor_events are from the same sensor_handle OR they are flush_complete_events
13998493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                // from the same sensor_handle AND the current connection is mapped to the
14008493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                // corresponding flush_complete_event.
140156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                if (buffer[i].type == SENSOR_TYPE_META_DATA) {
14028493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    if (this == mapFlushEventsToConnections[i]) {
140356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                        scratch[count++] = buffer[i];
140456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                    }
140556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                    ++i;
140656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                } else {
140756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                    // Regular sensor event, just copy it to the scratch buffer.
140856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                    scratch[count++] = buffer[i++];
140956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                }
14108493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            } while ((i<numEvents) && ((buffer[i].sensor == sensor_handle &&
14118493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                                        buffer[i].type != SENSOR_TYPE_META_DATA) ||
141256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                                       (buffer[i].type == SENSOR_TYPE_META_DATA  &&
14136c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                                        buffer[i].meta_data.sensor == sensor_handle)));
1414cf51001dbf28e9885fcacd4048902f1c75768fe9Mathias Agopian        }
14153560fb24b668675627934356f210d84d19bf4e56Mathias Agopian    } else {
14163560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        scratch = const_cast<sensors_event_t *>(buffer);
14173560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        count = numEvents;
1418cf51001dbf28e9885fcacd4048902f1c75768fe9Mathias Agopian    }
1419fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
14206c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    sendPendingFlushEventsLocked();
142156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    // Early return if there are no events for this connection.
142256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    if (count == 0) {
142356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        return status_t(NO_ERROR);
142456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    }
142556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
142656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#if DEBUG_CONNECTIONS
142756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella     mEventsReceived += count;
142856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#endif
142956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    if (mCacheSize != 0) {
143056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        // There are some events in the cache which need to be sent first. Copy this buffer to
143156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        // the end of cache.
143256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        if (mCacheSize + count <= mMaxCacheSize) {
143356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            memcpy(&mEventCache[mCacheSize], scratch, count * sizeof(sensors_event_t));
143456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            mCacheSize += count;
143556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        } else {
14366c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            // Check if any new sensors have registered on this connection which may have increased
14376c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            // the max cache size that is desired.
14386c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            if (mCacheSize + count < computeMaxCacheSizeLocked()) {
14396c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                reAllocateCacheLocked(scratch, count);
14406c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                return status_t(NO_ERROR);
14416c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            }
144256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            // Some events need to be dropped.
144356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            int remaningCacheSize = mMaxCacheSize - mCacheSize;
144456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            if (remaningCacheSize != 0) {
144556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                memcpy(&mEventCache[mCacheSize], scratch,
144656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                                                remaningCacheSize * sizeof(sensors_event_t));
144756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            }
144856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            int numEventsDropped = count - remaningCacheSize;
144956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            countFlushCompleteEventsLocked(mEventCache, numEventsDropped);
145056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            // Drop the first "numEventsDropped" in the cache.
145156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            memmove(mEventCache, &mEventCache[numEventsDropped],
145256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                    (mCacheSize - numEventsDropped) * sizeof(sensors_event_t));
145356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
145456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            // Copy the remainingEvents in scratch buffer to the end of cache.
145556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            memcpy(&mEventCache[mCacheSize - numEventsDropped], scratch + remaningCacheSize,
145656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                                            numEventsDropped * sizeof(sensors_event_t));
145756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        }
145856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        return status_t(NO_ERROR);
145956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    }
146056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
14616c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    int index_wake_up_event = findWakeUpSensorEventLocked(scratch, count);
14626c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    if (index_wake_up_event >= 0) {
14636c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        scratch[index_wake_up_event].flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
14646c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        ++mWakeLockRefCount;
1465e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#if DEBUG_CONNECTIONS
1466e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella        ++mTotalAcksNeeded;
1467e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#endif
14686c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    }
146956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
147056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    // NOTE: ASensorEvent and sensors_event_t are the same type.
147156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    ssize_t size = SensorEventQueue::write(mChannel,
147256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                                    reinterpret_cast<ASensorEvent const*>(scratch), count);
147356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    if (size < 0) {
147456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        // Write error, copy events to local cache.
14756c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        if (index_wake_up_event >= 0) {
14766c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            // If there was a wake_up sensor_event, reset the flag.
14776c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            scratch[index_wake_up_event].flags &= ~WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
14780ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella            if (mWakeLockRefCount > 0) {
14790ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella                --mWakeLockRefCount;
14800ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella            }
1481e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#if DEBUG_CONNECTIONS
1482e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella            --mTotalAcksNeeded;
1483e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#endif
14846c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        }
148556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        if (mEventCache == NULL) {
148656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            mMaxCacheSize = computeMaxCacheSizeLocked();
148756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            mEventCache = new sensors_event_t[mMaxCacheSize];
148856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            mCacheSize = 0;
148956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        }
149056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        memcpy(&mEventCache[mCacheSize], scratch, count * sizeof(sensors_event_t));
149156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        mCacheSize += count;
149256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
149356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        // Add this file descriptor to the looper to get a callback when this fd is available for
149456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        // writing.
14958a96955c8e14db40b16164236830fc9506a00872Aravind Akella        updateLooperRegistrationLocked(mService->getLooper());
149656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        return size;
149756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    }
149856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
149956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#if DEBUG_CONNECTIONS
150056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    if (size > 0) {
150156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        mEventsSent += count;
150256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    }
150356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#endif
150456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
150556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    return size < 0 ? status_t(size) : status_t(NO_ERROR);
150656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella}
150756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
15086c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akellavoid SensorService::SensorEventConnection::reAllocateCacheLocked(sensors_event_t const* scratch,
15096c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                                                                 int count) {
15106c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    sensors_event_t *eventCache_new;
15116c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    const int new_cache_size = computeMaxCacheSizeLocked();
15126c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    // Allocate new cache, copy over events from the old cache & scratch, free up memory.
15136c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    eventCache_new = new sensors_event_t[new_cache_size];
15146c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    memcpy(eventCache_new, mEventCache, mCacheSize * sizeof(sensors_event_t));
15156c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    memcpy(&eventCache_new[mCacheSize], scratch, count * sizeof(sensors_event_t));
15166c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
15176c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    ALOGD_IF(DEBUG_CONNECTIONS, "reAllocateCacheLocked maxCacheSize=%d %d", mMaxCacheSize,
15186c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            new_cache_size);
15196c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
15206c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    delete mEventCache;
15216c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    mEventCache = eventCache_new;
15226c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    mCacheSize += count;
15236c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    mMaxCacheSize = new_cache_size;
15246c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella}
15256c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
15266c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akellavoid SensorService::SensorEventConnection::sendPendingFlushEventsLocked() {
15276c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    ASensorEvent flushCompleteEvent;
15280ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella    memset(&flushCompleteEvent, 0, sizeof(flushCompleteEvent));
15296c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    flushCompleteEvent.type = SENSOR_TYPE_META_DATA;
15306c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    // Loop through all the sensors for this connection and check if there are any pending
15316c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    // flush complete events to be sent.
15326c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
15336c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        FlushInfo& flushInfo = mSensorInfo.editValueAt(i);
15346c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        while (flushInfo.mPendingFlushEventsToSend > 0) {
15350ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella            const int sensor_handle = mSensorInfo.keyAt(i);
15360ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella            flushCompleteEvent.meta_data.sensor = sensor_handle;
1537b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            bool wakeUpSensor = mService->getSensorFromHandle(sensor_handle).isWakeUpSensor();
1538b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            if (wakeUpSensor) {
1539b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella               ++mWakeLockRefCount;
15400ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella               flushCompleteEvent.flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
15410ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella            }
15426c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            ssize_t size = SensorEventQueue::write(mChannel, &flushCompleteEvent, 1);
15436c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            if (size < 0) {
1544b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella                if (wakeUpSensor) --mWakeLockRefCount;
15456c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                return;
15464c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
15476c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            ALOGD_IF(DEBUG_CONNECTIONS, "sent dropped flush complete event==%d ",
15486c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                    flushCompleteEvent.meta_data.sensor);
15496c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            flushInfo.mPendingFlushEventsToSend--;
15504c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
15514c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
15526c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella}
15536c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
1554b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::SensorEventConnection::writeToSocketFromCache() {
15555466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella    // At a time write at most half the size of the receiver buffer in SensorEventQueue OR
15565466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella    // half the size of the socket buffer allocated in BitTube whichever is smaller.
15575466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella    const int maxWriteSize = helpers::min(SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT/2,
15585466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            int(mService->mSocketBufferSize/(sizeof(sensors_event_t)*2)));
1559b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    Mutex::Autolock _l(mConnectionLock);
15605466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella    // Send pending flush complete events (if any)
15616c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    sendPendingFlushEventsLocked();
156256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    for (int numEventsSent = 0; numEventsSent < mCacheSize;) {
15635466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella        const int numEventsToWrite = helpers::min(mCacheSize - numEventsSent, maxWriteSize);
15646c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        int index_wake_up_event =
15656c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                  findWakeUpSensorEventLocked(mEventCache + numEventsSent, numEventsToWrite);
15666c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        if (index_wake_up_event >= 0) {
15676c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            mEventCache[index_wake_up_event + numEventsSent].flags |=
15686c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                    WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
15696c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            ++mWakeLockRefCount;
1570e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#if DEBUG_CONNECTIONS
1571e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella            ++mTotalAcksNeeded;
1572e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#endif
15736c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        }
157456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
157556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        ssize_t size = SensorEventQueue::write(mChannel,
157656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                          reinterpret_cast<ASensorEvent const*>(mEventCache + numEventsSent),
15776c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                          numEventsToWrite);
157856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        if (size < 0) {
15796c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            if (index_wake_up_event >= 0) {
15806c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                // If there was a wake_up sensor_event, reset the flag.
15816c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                mEventCache[index_wake_up_event + numEventsSent].flags  &=
15826c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                        ~WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
15830ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella                if (mWakeLockRefCount > 0) {
15840ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella                    --mWakeLockRefCount;
15850ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella                }
1586e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#if DEBUG_CONNECTIONS
1587e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella                --mTotalAcksNeeded;
1588e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#endif
15896c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            }
159056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            memmove(mEventCache, &mEventCache[numEventsSent],
159156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                                 (mCacheSize - numEventsSent) * sizeof(sensors_event_t));
159256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            ALOGD_IF(DEBUG_CONNECTIONS, "wrote %d events from cache size==%d ",
15936c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                    numEventsSent, mCacheSize);
159456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            mCacheSize -= numEventsSent;
159556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            return;
159656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        }
15976c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        numEventsSent += numEventsToWrite;
159856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#if DEBUG_CONNECTIONS
15996c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        mEventsSentFromCache += numEventsToWrite;
160056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#endif
1601fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
160256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    ALOGD_IF(DEBUG_CONNECTIONS, "wrote all events from cache size=%d ", mCacheSize);
160356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    // All events from the cache have been sent. Reset cache size to zero.
160456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    mCacheSize = 0;
16058a96955c8e14db40b16164236830fc9506a00872Aravind Akella    // There are no more events in the cache. We don't need to poll for write on the fd.
16068a96955c8e14db40b16164236830fc9506a00872Aravind Akella    // Update Looper registration.
16078a96955c8e14db40b16164236830fc9506a00872Aravind Akella    updateLooperRegistrationLocked(mService->getLooper());
1608fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1609fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1610c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akellavoid SensorService::SensorEventConnection::countFlushCompleteEventsLocked(
16110ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella                sensors_event_t const* scratch, const int numEventsDropped) {
16124c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    ALOGD_IF(DEBUG_CONNECTIONS, "dropping %d events ", numEventsDropped);
16134c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    // Count flushComplete events in the events that are about to the dropped. These will be sent
16144c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    // separately before the next batch of events.
16154c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    for (int j = 0; j < numEventsDropped; ++j) {
16164c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        if (scratch[j].type == SENSOR_TYPE_META_DATA) {
16174c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            FlushInfo& flushInfo = mSensorInfo.editValueFor(scratch[j].meta_data.sensor);
16184c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            flushInfo.mPendingFlushEventsToSend++;
16194c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            ALOGD_IF(DEBUG_CONNECTIONS, "increment pendingFlushCount %d",
16204c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                     flushInfo.mPendingFlushEventsToSend);
16214c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
16224c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
16234c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    return;
16244c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella}
16254c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
16266c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akellaint SensorService::SensorEventConnection::findWakeUpSensorEventLocked(
16276c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                       sensors_event_t const* scratch, const int count) {
16289a844cf78f09953145200b4074d47589257a408cAravind Akella    for (int i = 0; i < count; ++i) {
16299a844cf78f09953145200b4074d47589257a408cAravind Akella        if (mService->isWakeUpSensorEvent(scratch[i])) {
16306c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            return i;
16319a844cf78f09953145200b4074d47589257a408cAravind Akella        }
16329a844cf78f09953145200b4074d47589257a408cAravind Akella    }
16336c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    return -1;
16349a844cf78f09953145200b4074d47589257a408cAravind Akella}
16359a844cf78f09953145200b4074d47589257a408cAravind Akella
1636b3989276d17f2b083bec67b695d1078fb86c6c53Mathias Agopiansp<BitTube> SensorService::SensorEventConnection::getSensorChannel() const
1637fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
1638fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return mChannel;
1639fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1640fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1641fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::SensorEventConnection::enableDisable(
1642724d91d778e71c8186399f4955de14b54812b3edAravind Akella        int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
1643724d91d778e71c8186399f4955de14b54812b3edAravind Akella        int reservedFlags)
1644fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
1645fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    status_t err;
1646fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (enabled) {
1647724d91d778e71c8186399f4955de14b54812b3edAravind Akella        err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
1648b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                               reservedFlags, mOpPackageName);
164956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
1650fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    } else {
1651fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        err = mService->disable(this, handle);
1652fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
1653fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return err;
1654fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1655fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1656fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::SensorEventConnection::setEventRate(
1657724d91d778e71c8186399f4955de14b54812b3edAravind Akella        int handle, nsecs_t samplingPeriodNs)
1658fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
1659b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    return mService->setEventRate(this, handle, samplingPeriodNs, mOpPackageName);
1660fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1661fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1662701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akellastatus_t  SensorService::SensorEventConnection::flush() {
1663b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    return  mService->flushSensor(this, mOpPackageName);
1664724d91d778e71c8186399f4955de14b54812b3edAravind Akella}
16654c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
16668a96955c8e14db40b16164236830fc9506a00872Aravind Akellaint SensorService::SensorEventConnection::handleEvent(int fd, int events, void* /*data*/) {
166756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    if (events & ALOOPER_EVENT_HANGUP || events & ALOOPER_EVENT_ERROR) {
16688a96955c8e14db40b16164236830fc9506a00872Aravind Akella        {
16698a96955c8e14db40b16164236830fc9506a00872Aravind Akella            // If the Looper encounters some error, set the flag mDead, reset mWakeLockRefCount,
16708a96955c8e14db40b16164236830fc9506a00872Aravind Akella            // and remove the fd from Looper. Call checkWakeLockState to know if SensorService
16718a96955c8e14db40b16164236830fc9506a00872Aravind Akella            // can release the wake-lock.
16728a96955c8e14db40b16164236830fc9506a00872Aravind Akella            ALOGD_IF(DEBUG_CONNECTIONS, "%p Looper error %d", this, fd);
16738a96955c8e14db40b16164236830fc9506a00872Aravind Akella            Mutex::Autolock _l(mConnectionLock);
16748a96955c8e14db40b16164236830fc9506a00872Aravind Akella            mDead = true;
16758a96955c8e14db40b16164236830fc9506a00872Aravind Akella            mWakeLockRefCount = 0;
16768a96955c8e14db40b16164236830fc9506a00872Aravind Akella            updateLooperRegistrationLocked(mService->getLooper());
16778a96955c8e14db40b16164236830fc9506a00872Aravind Akella        }
16788a96955c8e14db40b16164236830fc9506a00872Aravind Akella        mService->checkWakeLockState();
1679a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        if (mDataInjectionMode) {
1680a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella            // If the Looper has encountered some error in data injection mode, reset SensorService
1681a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella            // back to normal mode.
1682a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella            mService->resetToNormalMode();
1683a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella            mDataInjectionMode = false;
1684a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        }
16858a96955c8e14db40b16164236830fc9506a00872Aravind Akella        return 1;
16869a844cf78f09953145200b4074d47589257a408cAravind Akella    }
168756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
168856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    if (events & ALOOPER_EVENT_INPUT) {
1689a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        unsigned char buf[sizeof(sensors_event_t)];
1690a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        ssize_t numBytesRead = ::recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
169156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        {
169256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella           Mutex::Autolock _l(mConnectionLock);
1693a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella           if (numBytesRead == sizeof(sensors_event_t)) {
1694a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               if (!mDataInjectionMode) {
1695a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella                   ALOGE("Data injected in normal mode, dropping event"
1696a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella                         "package=%s uid=%d", mPackageName.string(), mUid);
1697a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella                   // Unregister call backs.
1698a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella                   return 0;
1699a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               }
1700a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               SensorDevice& dev(SensorDevice::getInstance());
1701a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               sensors_event_t sensor_event;
1702a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               memset(&sensor_event, 0, sizeof(sensor_event));
1703a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               memcpy(&sensor_event, buf, sizeof(sensors_event_t));
1704a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               Sensor sensor = mService->getSensorFromHandle(sensor_event.sensor);
1705a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               sensor_event.type = sensor.getType();
1706b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav               dev.injectSensorData(&sensor_event);
1707e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#if DEBUG_CONNECTIONS
1708a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               ++mEventsReceived;
1709e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#endif
1710a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella           } else if (numBytesRead == sizeof(uint32_t)) {
1711a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               uint32_t numAcks = 0;
1712a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               memcpy(&numAcks, buf, sizeof(numBytesRead));
1713a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               // Sanity check to ensure  there are no read errors in recv, numAcks is always
1714a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               // within the range and not zero. If any of the above don't hold reset
1715a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               // mWakeLockRefCount to zero.
1716a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               if (numAcks > 0 && numAcks < mWakeLockRefCount) {
1717a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella                   mWakeLockRefCount -= numAcks;
1718a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               } else {
1719a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella                   mWakeLockRefCount = 0;
1720a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               }
1721a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella#if DEBUG_CONNECTIONS
1722a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               mTotalAcksReceived += numAcks;
1723a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella#endif
1724a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella           } else {
1725a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               // Read error, reset wakelock refcount.
1726a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               mWakeLockRefCount = 0;
1727a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella           }
172856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        }
172956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        // Check if wakelock can be released by sensorservice. mConnectionLock needs to be released
173056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        // here as checkWakeLockState() will need it.
173156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        if (mWakeLockRefCount == 0) {
173256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            mService->checkWakeLockState();
173356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        }
173456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        // continue getting callbacks.
173556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        return 1;
173656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    }
173756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
173856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    if (events & ALOOPER_EVENT_OUTPUT) {
1739b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        // send sensor data that is stored in mEventCache for this connection.
1740b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        mService->sendEventsFromCache(this);
17419a844cf78f09953145200b4074d47589257a408cAravind Akella    }
174256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    return 1;
174356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella}
174456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
174556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellaint SensorService::SensorEventConnection::computeMaxCacheSizeLocked() const {
1746b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    size_t fifoWakeUpSensors = 0;
1747b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    size_t fifoNonWakeUpSensors = 0;
174856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
174956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        const Sensor& sensor = mService->getSensorFromHandle(mSensorInfo.keyAt(i));
175056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        if (sensor.getFifoReservedEventCount() == sensor.getFifoMaxEventCount()) {
175156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            // Each sensor has a reserved fifo. Sum up the fifo sizes for all wake up sensors and
175256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            // non wake_up sensors.
175356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            if (sensor.isWakeUpSensor()) {
175456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                fifoWakeUpSensors += sensor.getFifoReservedEventCount();
175556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            } else {
175656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                fifoNonWakeUpSensors += sensor.getFifoReservedEventCount();
175756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            }
175856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        } else {
175956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            // Shared fifo. Compute the max of the fifo sizes for wake_up and non_wake up sensors.
176056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            if (sensor.isWakeUpSensor()) {
176156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                fifoWakeUpSensors = fifoWakeUpSensors > sensor.getFifoMaxEventCount() ?
176256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                                          fifoWakeUpSensors : sensor.getFifoMaxEventCount();
176356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
176456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            } else {
176556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                fifoNonWakeUpSensors = fifoNonWakeUpSensors > sensor.getFifoMaxEventCount() ?
176656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                                          fifoNonWakeUpSensors : sensor.getFifoMaxEventCount();
176756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
176856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            }
176956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        }
177056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella   }
177156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella   if (fifoWakeUpSensors + fifoNonWakeUpSensors == 0) {
177256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella       // It is extremely unlikely that there is a write failure in non batch mode. Return a cache
17736c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella       // size that is equal to that of the batch mode.
1774e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella       // ALOGW("Write failure in non-batch mode");
17756c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella       return MAX_SOCKET_BUFFER_SIZE_BATCHED/sizeof(sensors_event_t);
177656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella   }
177756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella   return fifoWakeUpSensors + fifoNonWakeUpSensors;
17789a844cf78f09953145200b4074d47589257a408cAravind Akella}
17799a844cf78f09953145200b4074d47589257a408cAravind Akella
1780fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// ---------------------------------------------------------------------------
1781fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}; // namespace android
1782fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1783