SensorService.cpp revision 841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1
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 sDump("android.permission.DUMP");
704342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
71fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorService()
728a96955c8e14db40b16164236830fc9506a00872Aravind Akella    : mInitCheck(NO_INIT), mSocketBufferSize(SOCKET_BUFFER_SIZE_NON_BATCHED),
738a96955c8e14db40b16164236830fc9506a00872Aravind Akella      mWakeLockAcquired(false)
74fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
75fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
76fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
77fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianvoid SensorService::onFirstRef()
78fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
79a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block    ALOGD("nuSensorService starting...");
80f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    SensorDevice& dev(SensorDevice::getInstance());
81fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
82f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    if (dev.initCheck() == NO_ERROR) {
83f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        sensor_t const* list;
847b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian        ssize_t count = dev.getSensorList(&list);
857b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian        if (count > 0) {
867b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            ssize_t orientationIndex = -1;
877b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            bool hasGyro = false;
887b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            uint32_t virtualSensorsNeeds =
897b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    (1<<SENSOR_TYPE_GRAVITY) |
907b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    (1<<SENSOR_TYPE_LINEAR_ACCELERATION) |
917b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    (1<<SENSOR_TYPE_ROTATION_VECTOR);
927b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian
937b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            mLastEventSeen.setCapacity(count);
947b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            for (ssize_t i=0 ; i<count ; i++) {
957b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                registerSensor( new HardwareSensor(list[i]) );
967b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                switch (list[i].type) {
977b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_ORIENTATION:
987b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        orientationIndex = i;
997b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        break;
1007b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_GYROSCOPE:
1010319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
1027b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        hasGyro = true;
1037b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        break;
1047b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_GRAVITY:
1057b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_LINEAR_ACCELERATION:
1067b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_ROTATION_VECTOR:
1077b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        virtualSensorsNeeds &= ~(1<<list[i].type);
1087b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        break;
1097b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                }
11050df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian            }
111fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1127b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            // it's safe to instantiate the SensorFusion object here
1137b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            // (it wants to be instantiated after h/w sensors have been
1147b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            // registered)
1157b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            const SensorFusion& fusion(SensorFusion::getInstance());
1167b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian
1170319306670b0344da99efa606b6f172dde575a39Mathias Agopian            // build the sensor list returned to users
1180319306670b0344da99efa606b6f172dde575a39Mathias Agopian            mUserSensorList = mSensorList;
1190319306670b0344da99efa606b6f172dde575a39Mathias Agopian
1207b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            if (hasGyro) {
1210319306670b0344da99efa606b6f172dde575a39Mathias Agopian                Sensor aSensor;
1227b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian
1230319306670b0344da99efa606b6f172dde575a39Mathias Agopian                // Add Android virtual sensors if they're not already
1240319306670b0344da99efa606b6f172dde575a39Mathias Agopian                // available in the HAL
1257b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian
1260319306670b0344da99efa606b6f172dde575a39Mathias Agopian                aSensor = registerVirtualSensor( new RotationVectorSensor() );
1270319306670b0344da99efa606b6f172dde575a39Mathias Agopian                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
1280319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    mUserSensorList.add(aSensor);
1290319306670b0344da99efa606b6f172dde575a39Mathias Agopian                }
130f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
1310319306670b0344da99efa606b6f172dde575a39Mathias Agopian                aSensor = registerVirtualSensor( new GravitySensor(list, count) );
1320319306670b0344da99efa606b6f172dde575a39Mathias Agopian                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) {
1330319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    mUserSensorList.add(aSensor);
1340319306670b0344da99efa606b6f172dde575a39Mathias Agopian                }
13533264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian
1360319306670b0344da99efa606b6f172dde575a39Mathias Agopian                aSensor = registerVirtualSensor( new LinearAccelerationSensor(list, count) );
1370319306670b0344da99efa606b6f172dde575a39Mathias Agopian                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) {
1380319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    mUserSensorList.add(aSensor);
1390319306670b0344da99efa606b6f172dde575a39Mathias Agopian                }
14033264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian
1410319306670b0344da99efa606b6f172dde575a39Mathias Agopian                aSensor = registerVirtualSensor( new OrientationSensor() );
1420319306670b0344da99efa606b6f172dde575a39Mathias Agopian                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
1430319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    // if we are doing our own rotation-vector, also add
1440319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    // the orientation sensor and remove the HAL provided one.
1450319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    mUserSensorList.replaceAt(aSensor, orientationIndex);
1467b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                }
1470319306670b0344da99efa606b6f172dde575a39Mathias Agopian
1480319306670b0344da99efa606b6f172dde575a39Mathias Agopian                // virtual debugging sensors are not added to mUserSensorList
1490319306670b0344da99efa606b6f172dde575a39Mathias Agopian                registerVirtualSensor( new CorrectedGyroSensor(list, count) );
1500319306670b0344da99efa606b6f172dde575a39Mathias Agopian                registerVirtualSensor( new GyroDriftSensor() );
151010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian            }
152010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian
15333264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian            // debugging sensor list
1540319306670b0344da99efa606b6f172dde575a39Mathias Agopian            mUserSensorListDebug = mSensorList;
15533264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian
1565466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            // Check if the device really supports batching by looking at the FIFO event
1575466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            // counts for each sensor.
1585466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            bool batchingSupported = false;
159b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            for (size_t i = 0; i < mSensorList.size(); ++i) {
1605466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                if (mSensorList[i].getFifoMaxEventCount() > 0) {
1615466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                    batchingSupported = true;
1625466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                    break;
1635466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                }
1645466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            }
1655466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella
1665466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            if (batchingSupported) {
1675466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                // Increase socket buffer size to a max of 100 KB for batching capabilities.
1685466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                mSocketBufferSize = MAX_SOCKET_BUFFER_SIZE_BATCHED;
1695466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            } else {
1705466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                mSocketBufferSize = SOCKET_BUFFER_SIZE_NON_BATCHED;
1715466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            }
1725466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella
1735466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            // Compare the socketBufferSize value against the system limits and limit
1745466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            // it to maxSystemSocketBufferSize if necessary.
1754c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            FILE *fp = fopen("/proc/sys/net/core/wmem_max", "r");
1764c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            char line[128];
1774c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            if (fp != NULL && fgets(line, sizeof(line), fp) != NULL) {
1784c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                line[sizeof(line) - 1] = '\0';
1795466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                size_t maxSystemSocketBufferSize;
1805466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                sscanf(line, "%zu", &maxSystemSocketBufferSize);
1815466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                if (mSocketBufferSize > maxSystemSocketBufferSize) {
1825466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                    mSocketBufferSize = maxSystemSocketBufferSize;
1834c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                }
1844c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
1854c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            if (fp) {
1864c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                fclose(fp);
1874c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
1884c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
1899a844cf78f09953145200b4074d47589257a408cAravind Akella            mWakeLockAcquired = false;
19056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            mLooper = new Looper(false);
1918493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
1928493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            mSensorEventBuffer = new sensors_event_t[minBufferSize];
1938493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            mSensorEventScratch = new sensors_event_t[minBufferSize];
1948493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize];
195a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella            mCurrentOperatingMode = NORMAL;
1967830ef3dd0ff3749d974c2dd85a8fa59dc47aecaAravind Akella
19718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            mNextSensorRegIndex = 0;
19818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            for (int i = 0; i < SENSOR_REGISTRATIONS_BUF_SIZE; ++i) {
19918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                mLastNSensorRegistrations.push();
20018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            }
20118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella
20218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            mInitCheck = NO_ERROR;
203b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            mAckReceiver = new SensorEventAckReceiver(this);
204b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
2057830ef3dd0ff3749d974c2dd85a8fa59dc47aecaAravind Akella            run("SensorService", PRIORITY_URGENT_DISPLAY);
2067b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian        }
207fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
208fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
209fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
2100319306670b0344da99efa606b6f172dde575a39Mathias AgopianSensor SensorService::registerSensor(SensorInterface* s)
211f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{
212f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    sensors_event_t event;
213f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    memset(&event, 0, sizeof(event));
214f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
215f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    const Sensor sensor(s->getSensor());
216f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    // add to the sensor list (returned to clients)
217f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    mSensorList.add(sensor);
218f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    // add to our handle->SensorInterface mapping
219f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    mSensorMap.add(sensor.getHandle(), s);
220f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    // create an entry in the mLastEventSeen array
221444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    mLastEventSeen.add(sensor.getHandle(), NULL);
2220319306670b0344da99efa606b6f172dde575a39Mathias Agopian
2230319306670b0344da99efa606b6f172dde575a39Mathias Agopian    return sensor;
224f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
225f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
2260319306670b0344da99efa606b6f172dde575a39Mathias AgopianSensor SensorService::registerVirtualSensor(SensorInterface* s)
227f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{
2280319306670b0344da99efa606b6f172dde575a39Mathias Agopian    Sensor sensor = registerSensor(s);
229f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    mVirtualSensorList.add( s );
2300319306670b0344da99efa606b6f172dde575a39Mathias Agopian    return sensor;
231f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
232f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
233fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::~SensorService()
234fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
235f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    for (size_t i=0 ; i<mSensorMap.size() ; i++)
236f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        delete mSensorMap.valueAt(i);
237fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
238fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
2394949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akellastatus_t SensorService::dump(int fd, const Vector<String16>& args)
240fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
241fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    String8 result;
2421cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
243ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian        result.appendFormat("Permission Denial: "
244700180487ffec09d9df1657b018a7caadac24b75Aravind Akella                "can't dump SensorService from pid=%d, uid=%d\n",
245fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian                IPCThreadState::self()->getCallingPid(),
246fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian                IPCThreadState::self()->getCallingUid());
247444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    } else {
248841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella        if (args.size() > 2) {
2494949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella           return INVALID_OPERATION;
2504949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        }
2514949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        Mutex::Autolock _l(mLock);
2524949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        SensorDevice& dev(SensorDevice::getInstance());
253841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella        if (args.size() == 2 && args[0] == String16("restrict")) {
254444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            // If already in restricted mode. Ignore.
255444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            if (mCurrentOperatingMode == RESTRICTED) {
256444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                return status_t(NO_ERROR);
257444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            }
258444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            // If in any mode other than normal, ignore.
259444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            if (mCurrentOperatingMode != NORMAL) {
260444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                return INVALID_OPERATION;
261444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            }
262a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella            mCurrentOperatingMode = RESTRICTED;
2634949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            dev.disableAllSensors();
2644949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            // Clear all pending flush connections for all active sensors. If one of the active
2654949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            // connections has called flush() and the underlying sensor has been disabled before a
2664949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            // flush complete event is returned, we need to remove the connection from this queue.
2674949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            for (size_t i=0 ; i< mActiveSensors.size(); ++i) {
2684949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella                mActiveSensors.valueAt(i)->clearAllPendingFlushConnections();
2694949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            }
270841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            mWhiteListedPackage.setTo(String8(args[1]));
271444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            return status_t(NO_ERROR);
272444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        } else if (args.size() == 1 && args[0] == String16("enable")) {
273444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            // If currently in restricted mode, reset back to NORMAL mode else ignore.
274444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            if (mCurrentOperatingMode == RESTRICTED) {
275444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                mCurrentOperatingMode = NORMAL;
276444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                dev.enableAllSensors();
2776c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            }
278841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            if (mCurrentOperatingMode == DATA_INJECTION) {
279841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella               resetToNormalModeLocked();
280841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            }
281841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            mWhiteListedPackage.clear();
282444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            return status_t(NO_ERROR);
283841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella        } else if (args.size() == 2 && args[0] == String16("data_injection")) {
284841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            if (mCurrentOperatingMode == NORMAL) {
285841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                dev.disableAllSensors();
286841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                status_t err = dev.setMode(DATA_INJECTION);
287841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                if (err == NO_ERROR) {
288841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                    mCurrentOperatingMode = DATA_INJECTION;
289841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                } else {
290841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                    // Re-enable sensors.
291841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                    dev.enableAllSensors();
292841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                }
293841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                mWhiteListedPackage.setTo(String8(args[1]));
294841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                return NO_ERROR;
295841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            } else if (mCurrentOperatingMode == DATA_INJECTION) {
296841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                // Already in DATA_INJECTION mode. Treat this as a no_op.
297841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                return NO_ERROR;
298841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            } else {
299841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                // Transition to data injection mode supported only from NORMAL mode.
300841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                return INVALID_OPERATION;
301841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            }
302ee155cadb23e84542cbf445c2aac89ae63df4cc7Aravind Akella        } else if (mSensorList.size() == 0) {
303ee155cadb23e84542cbf445c2aac89ae63df4cc7Aravind Akella            result.append("No Sensors on the device\n");
304444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        } else {
305444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            // Default dump the sensor list and debugging information.
306444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            result.append("Sensor List:\n");
307444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            for (size_t i=0 ; i<mSensorList.size() ; i++) {
308444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                const Sensor& s(mSensorList[i]);
309444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                result.appendFormat(
310444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        "%-15s| %-10s| version=%d |%-20s| 0x%08x | \"%s\" | type=%d |",
311444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        s.getName().string(),
312444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        s.getVendor().string(),
313444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        s.getVersion(),
314444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        s.getStringType().string(),
315444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        s.getHandle(),
316444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        s.getRequiredPermission().string(),
317444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        s.getType());
318444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella
319444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                const int reportingMode = s.getReportingMode();
320444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                if (reportingMode == AREPORTING_MODE_CONTINUOUS) {
321444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.append(" continuous | ");
322444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                } else if (reportingMode == AREPORTING_MODE_ON_CHANGE) {
323444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.append(" on-change | ");
324444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                } else if (reportingMode == AREPORTING_MODE_ONE_SHOT) {
325444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.append(" one-shot | ");
326444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                } else {
327444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.append(" special-trigger | ");
328444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                }
3296c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
330444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                if (s.getMaxDelay() > 0) {
331444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.appendFormat("minRate=%.2fHz | ", 1e6f / s.getMaxDelay());
332444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                } else {
333444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.appendFormat("maxDelay=%dus |", s.getMaxDelay());
334444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                }
3350e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella
336444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                if (s.getMinDelay() > 0) {
337444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.appendFormat("maxRate=%.2fHz | ", 1e6f / s.getMinDelay());
338444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                } else {
339444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.appendFormat("minDelay=%dus |", s.getMinDelay());
340444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                }
3410e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella
342444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                if (s.getFifoMaxEventCount() > 0) {
343444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.appendFormat("FifoMax=%d events | ",
344444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                            s.getFifoMaxEventCount());
345444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                } else {
346444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.append("no batching | ");
347444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                }
3486c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
349444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                if (s.isWakeUpSensor()) {
350444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.appendFormat("wakeUp | ");
351444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                } else {
352444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.appendFormat("non-wakeUp | ");
353444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                }
354ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian
35518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                int bufIndex = mLastEventSeen.indexOfKey(s.getHandle());
35618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                if (bufIndex >= 0) {
35718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                    const CircularBuffer* buf = mLastEventSeen.valueAt(bufIndex);
35818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                    if (buf != NULL && s.getRequiredPermission().isEmpty()) {
35918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                        buf->printBuffer(result);
36018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                    } else {
36118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                        result.append("last=<> \n");
36218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                    }
363444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                }
364444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                result.append("\n");
365444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            }
366444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            SensorFusion::getInstance().dump(result);
367444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            SensorDevice::getInstance().dump(result);
368444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella
369444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            result.append("Active sensors:\n");
370444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            for (size_t i=0 ; i<mActiveSensors.size() ; i++) {
371444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                int handle = mActiveSensors.keyAt(i);
372444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                result.appendFormat("%s (handle=0x%08x, connections=%zu)\n",
373444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        getSensorName(handle).string(),
374444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        handle,
375444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        mActiveSensors.valueAt(i)->getNumConnections());
376ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            }
3774c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
378444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            result.appendFormat("Socket Buffer size = %d events\n",
379444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                                mSocketBufferSize/sizeof(sensors_event_t));
38018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            result.appendFormat("WakeLock Status: %s \n", mWakeLockAcquired ? "acquired" :
38118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                    "not held");
382444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            result.appendFormat("Mode :");
383444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            switch(mCurrentOperatingMode) {
384444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella               case NORMAL:
385444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                   result.appendFormat(" NORMAL\n");
386444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                   break;
387444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella               case RESTRICTED:
388841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                   result.appendFormat(" RESTRICTED : %s\n", mWhiteListedPackage.string());
389444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                   break;
390444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella               case DATA_INJECTION:
391841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                   result.appendFormat(" DATA_INJECTION : %s\n", mWhiteListedPackage.string());
392444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            }
393444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            result.appendFormat("%zd active connections\n", mActiveConnections.size());
3944c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
395444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            for (size_t i=0 ; i < mActiveConnections.size() ; i++) {
396444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                sp<SensorEventConnection> connection(mActiveConnections[i].promote());
397444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                if (connection != 0) {
398444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.appendFormat("Connection Number: %zu \n", i);
399444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    connection->dump(result);
400444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                }
4014c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
40218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella
40318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            result.appendFormat("Previous Registrations:\n");
40418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            // Log in the reverse chronological order.
40518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            int currentIndex = (mNextSensorRegIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) %
40618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                SENSOR_REGISTRATIONS_BUF_SIZE;
40718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            const int startIndex = currentIndex;
40818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            do {
40918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                const SensorRegistrationInfo& reg_info = mLastNSensorRegistrations[currentIndex];
41018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                if (SensorRegistrationInfo::isSentinel(reg_info)) {
41118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                    // Ignore sentinel, proceed to next item.
41218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                    currentIndex = (currentIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) %
41318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                        SENSOR_REGISTRATIONS_BUF_SIZE;
41418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                    continue;
41518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                }
41618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                if (reg_info.mActivated) {
41718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                   result.appendFormat("%02d:%02d:%02d activated package=%s handle=0x%08x "
41818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                           "samplingRate=%dus maxReportLatency=%dus\n",
41918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                           reg_info.mHour, reg_info.mMin, reg_info.mSec,
42018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                           reg_info.mPackageName.string(), reg_info.mSensorHandle,
42118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                           reg_info.mSamplingRateUs, reg_info.mMaxReportLatencyUs);
42218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                } else {
42318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                   result.appendFormat("%02d:%02d:%02d de-activated package=%s handle=0x%08x\n",
42418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                           reg_info.mHour, reg_info.mMin, reg_info.mSec,
42518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                           reg_info.mPackageName.string(), reg_info.mSensorHandle);
42618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                }
42718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                currentIndex = (currentIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) %
42818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                        SENSOR_REGISTRATIONS_BUF_SIZE;
42918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            } while(startIndex != currentIndex);
4304c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
431fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
432fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    write(fd, result.string(), result.size());
433fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return NO_ERROR;
434fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
435fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
4369a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::cleanupAutoDisabledSensorLocked(const sp<SensorEventConnection>& connection,
4374342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        sensors_event_t const* buffer, const int count) {
4384342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    for (int i=0 ; i<count ; i++) {
4394342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        int handle = buffer[i].sensor;
4408493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        if (buffer[i].type == SENSOR_TYPE_META_DATA) {
4418493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            handle = buffer[i].meta_data.sensor;
4428493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        }
4430e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella        if (connection->hasSensor(handle)) {
4440e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            SensorInterface* sensor = mSensorMap.valueFor(handle);
4450e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            // If this buffer has an event from a one_shot sensor and this connection is registered
4460e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            // for this particular one_shot sensor, try cleaning up the connection.
4470e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            if (sensor != NULL &&
4480e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella                sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
4490e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella                sensor->autoDisable(connection.get(), handle);
4509a844cf78f09953145200b4074d47589257a408cAravind Akella                cleanupWithoutDisableLocked(connection, handle);
4514342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            }
452a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
4534342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
454a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella   }
4554342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh}
4564342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
457fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::threadLoop()
458fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
459a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block    ALOGD("nuSensorService thread starting...");
460fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
46190ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    // each virtual sensor could generate an event per "real" event, that's why we need
46290ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    // to size numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT.
46390ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    // in practice, this is too aggressive, but guaranteed to be enough.
46490ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
46590ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    const size_t numEventMax = minBufferSize / (1 + mVirtualSensorList.size());
46690ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian
467f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    SensorDevice& device(SensorDevice::getInstance());
468f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    const size_t vcount = mVirtualSensorList.size();
469fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
4704342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    const int halVersion = device.getHalDeviceVersion();
471fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    do {
4728493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
4738493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        if (count < 0) {
474f5a1230d322c14c42331d0a1536b50c87742973bSteve Block            ALOGE("sensor poll failed (%s)", strerror(-count));
475fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            break;
476fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
47756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
47856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        // Reset sensors_event_t.flags to zero for all events in the buffer.
47956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        for (int i = 0; i < count; i++) {
4808493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella             mSensorEventBuffer[i].flags = 0;
48156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        }
482e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella
483e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella        // Make a copy of the connection vector as some connections may be removed during the
484e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella        // course of this loop (especially when one-shot sensor events are present in the
485e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella        // sensor_event buffer). Promote all connections to StrongPointers before the lock is
486e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella        // acquired. If the destructor of the sp gets called when the lock is acquired, it may
487e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella        // result in a deadlock as ~SensorEventConnection() needs to acquire mLock again for
488e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella        // cleanup. So copy all the strongPointers to a vector before the lock is acquired.
489e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella        SortedVector< sp<SensorEventConnection> > activeConnections;
490b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        populateActiveConnections(&activeConnections);
4919a844cf78f09953145200b4074d47589257a408cAravind Akella        Mutex::Autolock _l(mLock);
4929a844cf78f09953145200b4074d47589257a408cAravind Akella        // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The
4939a844cf78f09953145200b4074d47589257a408cAravind Akella        // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock,
4949a844cf78f09953145200b4074d47589257a408cAravind Akella        // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should
4959a844cf78f09953145200b4074d47589257a408cAravind Akella        // not be interleaved with decrementing SensorEventConnection::mWakeLockRefCount and
4969a844cf78f09953145200b4074d47589257a408cAravind Akella        // releasing the wakelock.
4979a844cf78f09953145200b4074d47589257a408cAravind Akella        bool bufferHasWakeUpEvent = false;
4984342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        for (int i = 0; i < count; i++) {
4998493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            if (isWakeUpSensorEvent(mSensorEventBuffer[i])) {
5009a844cf78f09953145200b4074d47589257a408cAravind Akella                bufferHasWakeUpEvent = true;
5019a844cf78f09953145200b4074d47589257a408cAravind Akella                break;
5024342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            }
5034342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
5044342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
5059a844cf78f09953145200b4074d47589257a408cAravind Akella        if (bufferHasWakeUpEvent && !mWakeLockAcquired) {
506b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            setWakeLockAcquiredLocked(true);
5079a844cf78f09953145200b4074d47589257a408cAravind Akella        }
5088493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        recordLastValueLocked(mSensorEventBuffer, count);
50994e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian
510f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        // handle virtual sensors
511f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        if (count && vcount) {
5128493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            sensors_event_t const * const event = mSensorEventBuffer;
5139a844cf78f09953145200b4074d47589257a408cAravind Akella            const size_t activeVirtualSensorCount = mActiveVirtualSensors.size();
514f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            if (activeVirtualSensorCount) {
515f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                size_t k = 0;
516984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                SensorFusion& fusion(SensorFusion::getInstance());
517984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                if (fusion.isEnabled()) {
518984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                    for (size_t i=0 ; i<size_t(count) ; i++) {
519984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                        fusion.process(event[i]);
520984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                    }
521984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                }
522d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) {
523f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {
524d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                        if (count + k >= minBufferSize) {
525d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                            ALOGE("buffer too small to hold all events: "
526db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn                                    "count=%zd, k=%zu, size=%zu",
527d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                                    count, k, minBufferSize);
528d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                            break;
529d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                        }
530f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                        sensors_event_t out;
5319a844cf78f09953145200b4074d47589257a408cAravind Akella                        SensorInterface* si = mActiveVirtualSensors.valueAt(j);
532d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                        if (si->process(&out, event[i])) {
5338493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                            mSensorEventBuffer[count + k] = out;
534f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                            k++;
535f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                        }
536f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    }
537f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                }
538f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                if (k) {
539f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    // record the last synthesized values
5408493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    recordLastValueLocked(&mSensorEventBuffer[count], k);
541f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    count += k;
542f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    // sort the buffer by time-stamps
5438493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    sortEventBuffer(mSensorEventBuffer, count);
544f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                }
545f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            }
546f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        }
547f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
5484342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // handle backward compatibility for RotationVector sensor
5494342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) {
5504342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            for (int i = 0; i < count; i++) {
5518493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                if (mSensorEventBuffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) {
5524342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                    // All the 4 components of the quaternion should be available
5534342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                    // No heading accuracy. Set it to -1
5548493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    mSensorEventBuffer[i].data[4] = -1;
5558493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                }
5568493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            }
5578493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        }
5588493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella
5598493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        // Map flush_complete_events in the buffer to SensorEventConnections which called
5608493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        // flush on the hardware sensor. mapFlushEventsToConnections[i] will be the
5618493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        // SensorEventConnection mapped to the corresponding flush_complete_event in
5628493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        // mSensorEventBuffer[i] if such a mapping exists (NULL otherwise).
5638493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        for (int i = 0; i < count; ++i) {
5648493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            mMapFlushEventsToConnections[i] = NULL;
5658493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            if (mSensorEventBuffer[i].type == SENSOR_TYPE_META_DATA) {
5668493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                const int sensor_handle = mSensorEventBuffer[i].meta_data.sensor;
5678493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                SensorRecord* rec = mActiveSensors.valueFor(sensor_handle);
5688493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                if (rec != NULL) {
5698493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    mMapFlushEventsToConnections[i] = rec->getFirstPendingFlushConnection();
5708493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    rec->removeFirstPendingFlushConnection();
5714342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                }
5724342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            }
5734342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
5744342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
5759a844cf78f09953145200b4074d47589257a408cAravind Akella        // Send our events to clients. Check the state of wake lock for each client and release the
5769a844cf78f09953145200b4074d47589257a408cAravind Akella        // lock if none of the clients need it.
5779a844cf78f09953145200b4074d47589257a408cAravind Akella        bool needsWakeLock = false;
5788493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        size_t numConnections = activeConnections.size();
5798493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        for (size_t i=0 ; i < numConnections; ++i) {
580e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella            if (activeConnections[i] != 0) {
581e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella                activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,
5828493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                        mMapFlushEventsToConnections);
583e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella                needsWakeLock |= activeConnections[i]->needsWakeLock();
5848493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                // If the connection has one-shot sensors, it may be cleaned up after first trigger.
5858493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                // Early check for one-shot sensors.
586e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella                if (activeConnections[i]->hasOneShotSensors()) {
587e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella                    cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer,
588e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella                            count);
5898493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                }
590fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            }
591fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
5924342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
5939a844cf78f09953145200b4074d47589257a408cAravind Akella        if (mWakeLockAcquired && !needsWakeLock) {
594b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            setWakeLockAcquiredLocked(false);
5959a844cf78f09953145200b4074d47589257a408cAravind Akella        }
5968493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella    } while (!Thread::exitPending());
597fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
5983c20fbed7f3a916ced10f2ed5a272271b7d81edeSteve Block    ALOGW("Exiting SensorService::threadLoop => aborting...");
5991a62301fc58cd2af18239b0415813461bf5fc41bMathias Agopian    abort();
600fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return false;
601fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
602fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
60356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellasp<Looper> SensorService::getLooper() const {
60456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    return mLooper;
60556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella}
60656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
607b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::resetAllWakeLockRefCounts() {
608b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    SortedVector< sp<SensorEventConnection> > activeConnections;
609b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    populateActiveConnections(&activeConnections);
610b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    {
611b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        Mutex::Autolock _l(mLock);
612b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        for (size_t i=0 ; i < activeConnections.size(); ++i) {
613b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            if (activeConnections[i] != 0) {
614b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella                activeConnections[i]->resetWakeLockRefCount();
615b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            }
616b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        }
617b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        setWakeLockAcquiredLocked(false);
618b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    }
619b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
620b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
621b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::setWakeLockAcquiredLocked(bool acquire) {
622b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    if (acquire) {
623b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        if (!mWakeLockAcquired) {
624b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
625b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            mWakeLockAcquired = true;
626b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        }
627b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        mLooper->wake();
628b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    } else {
629b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        if (mWakeLockAcquired) {
630b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            release_wake_lock(WAKE_LOCK_NAME);
631b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            mWakeLockAcquired = false;
632b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        }
633b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    }
634b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
635b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
636b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellabool SensorService::isWakeLockAcquired() {
637b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    Mutex::Autolock _l(mLock);
638b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    return mWakeLockAcquired;
639b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
640b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
64156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellabool SensorService::SensorEventAckReceiver::threadLoop() {
64256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    ALOGD("new thread SensorEventAckReceiver");
643b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    sp<Looper> looper = mService->getLooper();
64456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    do {
645b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        bool wakeLockAcquired = mService->isWakeLockAcquired();
646b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        int timeout = -1;
647b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        if (wakeLockAcquired) timeout = 5000;
648b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        int ret = looper->pollOnce(timeout);
649b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        if (ret == ALOOPER_POLL_TIMEOUT) {
650b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella           mService->resetAllWakeLockRefCounts();
651b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        }
65256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    } while(!Thread::exitPending());
65356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    return false;
65456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella}
65556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
6569a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::recordLastValueLocked(
6574b84704b97300eff3ebfab85652e64d54149d205Aravind Akella        const sensors_event_t* buffer, size_t count) {
6584b84704b97300eff3ebfab85652e64d54149d205Aravind Akella    for (size_t i = 0; i < count; i++) {
659444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        if (buffer[i].type != SENSOR_TYPE_META_DATA) {
660444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            CircularBuffer* &circular_buf = mLastEventSeen.editValueFor(buffer[i].sensor);
661444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            if (circular_buf == NULL) {
662444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                circular_buf = new CircularBuffer(buffer[i].type);
6634b84704b97300eff3ebfab85652e64d54149d205Aravind Akella            }
664444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            circular_buf->addEvent(buffer[i]);
66594e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian        }
66694e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian    }
66794e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian}
66894e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian
669f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopianvoid SensorService::sortEventBuffer(sensors_event_t* buffer, size_t count)
670f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{
671f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    struct compar {
672f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        static int cmp(void const* lhs, void const* rhs) {
673f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            sensors_event_t const* l = static_cast<sensors_event_t const*>(lhs);
674f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            sensors_event_t const* r = static_cast<sensors_event_t const*>(rhs);
675a5c106a4f0afcf061728a1cb7c8c3b908728575dMathias Agopian            return l->timestamp - r->timestamp;
676f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        }
677f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    };
678f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    qsort(buffer, count, sizeof(sensors_event_t), compar::cmp);
679f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
680f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
6815d2707214dfb97bd8dfcc6620be36841d3c82420Mathias AgopianString8 SensorService::getSensorName(int handle) const {
682010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian    size_t count = mUserSensorList.size();
6835d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
684010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian        const Sensor& sensor(mUserSensorList[i]);
6855d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian        if (sensor.getHandle() == handle) {
6865d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian            return sensor.getName();
6875d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian        }
6885d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian    }
6895d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian    String8 result("unknown");
6905d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian    return result;
6915d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian}
6925d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian
693b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akellabool SensorService::isVirtualSensor(int handle) const {
694b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella    SensorInterface* sensor = mSensorMap.valueFor(handle);
695b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella    return sensor->isVirtual();
696b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella}
697b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella
6989a844cf78f09953145200b4074d47589257a408cAravind Akellabool SensorService::isWakeUpSensorEvent(const sensors_event_t& event) const {
6997869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan    int handle = event.sensor;
7007869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan    if (event.type == SENSOR_TYPE_META_DATA) {
7017869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan        handle = event.meta_data.sensor;
7027869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan    }
7037869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan    SensorInterface* sensor = mSensorMap.valueFor(handle);
7047869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan    return sensor != NULL && sensor->getSensor().isWakeUpSensor();
7059a844cf78f09953145200b4074d47589257a408cAravind Akella}
7069a844cf78f09953145200b4074d47589257a408cAravind Akella
7076c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind AkellaSensorService::SensorRecord * SensorService::getSensorRecord(int handle) {
7086c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella     return mActiveSensors.valueFor(handle);
7096c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella}
7106c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
711b412f6e203b38f8047f760261a5e3dc6d0722f08SvetoslavVector<Sensor> SensorService::getSensorList(const String16& opPackageName)
712fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
71333264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian    char value[PROPERTY_VALUE_MAX];
71433264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian    property_get("debug.sensors", value, "0");
715700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    const Vector<Sensor>& initialSensorList = (atoi(value)) ?
716700180487ffec09d9df1657b018a7caadac24b75Aravind Akella            mUserSensorListDebug : mUserSensorList;
717700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    Vector<Sensor> accessibleSensorList;
718700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    for (size_t i = 0; i < initialSensorList.size(); i++) {
719700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        Sensor sensor = initialSensorList[i];
720b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        if (canAccessSensor(sensor, "getSensorList", opPackageName)) {
721700180487ffec09d9df1657b018a7caadac24b75Aravind Akella            accessibleSensorList.add(sensor);
722700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        } else {
723b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            ALOGI("Skipped sensor %s because it requires permission %s and app op %d",
7245f6199373dc1e07d2ee5edbae7ecfa08a065492eBernhard Rosenkränzer                  sensor.getName().string(),
725b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                  sensor.getRequiredPermission().string(),
726b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                  sensor.getRequiredAppOp());
727700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        }
72833264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian    }
729700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    return accessibleSensorList;
730fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
731fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
732a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellasp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName,
733b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        int requestedMode, const String16& opPackageName) {
734a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    // Only 2 modes supported for a SensorEventConnection ... NORMAL and DATA_INJECTION.
735a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    if (requestedMode != NORMAL && requestedMode != DATA_INJECTION) {
736a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        return NULL;
737a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    }
738a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
739a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    Mutex::Autolock _l(mLock);
740841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    // To create a client in DATA_INJECTION mode to inject data, SensorService should already be
741841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    // operating in DI mode.
742841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    if (requestedMode == DATA_INJECTION) {
743841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella        if (mCurrentOperatingMode != DATA_INJECTION) return NULL;
744841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella        if (!isWhiteListedPackage(packageName)) return NULL;
745841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    }
746841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella
7475307d17fe33fc26eeeacd6339a9fbfe96cf56873Mathias Agopian    uid_t uid = IPCThreadState::self()->getCallingUid();
748a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    sp<SensorEventConnection> result(new SensorEventConnection(this, uid, packageName,
749b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            requestedMode == DATA_INJECTION, opPackageName));
750a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    if (requestedMode == DATA_INJECTION) {
751a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        if (mActiveConnections.indexOf(result) < 0) {
752a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella            mActiveConnections.add(result);
753a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        }
754a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        // Add the associated file descriptor to the Looper for polling whenever there is data to
755a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        // be injected.
756a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        result->updateLooperRegistration(mLooper);
757a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    }
758fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return result;
759fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
760fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
761841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akellaint SensorService::isDataInjectionEnabled() {
762a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    Mutex::Autolock _l(mLock);
763841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    return (mCurrentOperatingMode == DATA_INJECTION);
764a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella}
765a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
766a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatus_t SensorService::resetToNormalMode() {
767a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    Mutex::Autolock _l(mLock);
768a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    return resetToNormalModeLocked();
769a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella}
770a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
771a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatus_t SensorService::resetToNormalModeLocked() {
772a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    SensorDevice& dev(SensorDevice::getInstance());
773a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    dev.enableAllSensors();
774a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    status_t err = dev.setMode(NORMAL);
775a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    mCurrentOperatingMode = NORMAL;
776a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    return err;
777a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella}
778a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
779db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopianvoid SensorService::cleanupConnection(SensorEventConnection* c)
780fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
781fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    Mutex::Autolock _l(mLock);
782db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian    const wp<SensorEventConnection> connection(c);
7837c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    size_t size = mActiveSensors.size();
784db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn    ALOGD_IF(DEBUG_CONNECTIONS, "%zu active sensors", size);
7857c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    for (size_t i=0 ; i<size ; ) {
786db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        int handle = mActiveSensors.keyAt(i);
787db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        if (c->hasSensor(handle)) {
788db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn            ALOGD_IF(DEBUG_CONNECTIONS, "%zu: disabling handle=0x%08x", i, handle);
789f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            SensorInterface* sensor = mSensorMap.valueFor( handle );
790f5a1230d322c14c42331d0a1536b50c87742973bSteve Block            ALOGE_IF(!sensor, "mSensorMap[handle=0x%08x] is null!", handle);
791f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            if (sensor) {
792db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian                sensor->activate(c, false);
793f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            }
7948a96955c8e14db40b16164236830fc9506a00872Aravind Akella            c->removeSensor(handle);
795db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        }
796db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        SensorRecord* rec = mActiveSensors.valueAt(i);
797db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn        ALOGE_IF(!rec, "mActiveSensors[%zu] is null (handle=0x%08x)!", i, handle);
798a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block        ALOGD_IF(DEBUG_CONNECTIONS,
799db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn                "removing connection %p for sensor[%zu].handle=0x%08x",
800a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian                c, i, handle);
801a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian
802db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        if (rec && rec->removeConnection(connection)) {
803a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block            ALOGD_IF(DEBUG_CONNECTIONS, "... and it was the last connection");
8047c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            mActiveSensors.removeItemsAt(i, 1);
805f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            mActiveVirtualSensors.removeItem(handle);
8067c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            delete rec;
8077c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            size--;
8087c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian        } else {
8097c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            i++;
810fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
811fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
8128a96955c8e14db40b16164236830fc9506a00872Aravind Akella    c->updateLooperRegistration(mLooper);
8137c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    mActiveConnections.remove(connection);
814787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian    BatteryService::cleanup(c->getUid());
8159a844cf78f09953145200b4074d47589257a408cAravind Akella    if (c->needsWakeLock()) {
8169a844cf78f09953145200b4074d47589257a408cAravind Akella        checkWakeLockStateLocked();
8179a844cf78f09953145200b4074d47589257a408cAravind Akella    }
818fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
819fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
820700180487ffec09d9df1657b018a7caadac24b75Aravind AkellaSensor SensorService::getSensorFromHandle(int handle) const {
821700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    return mSensorMap.valueFor(handle)->getSensor();
822700180487ffec09d9df1657b018a7caadac24b75Aravind Akella}
823700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
824fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::enable(const sp<SensorEventConnection>& connection,
825b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags,
826b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        const String16& opPackageName)
827fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
82850df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian    if (mInitCheck != NO_ERROR)
82950df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian        return mInitCheck;
83050df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
831f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    SensorInterface* sensor = mSensorMap.valueFor(handle);
832ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    if (sensor == NULL) {
833ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        return BAD_VALUE;
834ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    }
835700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
836b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (!canAccessSensor(sensor->getSensor(), "Tried enabling", opPackageName)) {
837700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return BAD_VALUE;
838700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
839700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
840ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    Mutex::Autolock _l(mLock);
841841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    if ((mCurrentOperatingMode == RESTRICTED || mCurrentOperatingMode == DATA_INJECTION)
842841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella           && !isWhiteListedPackage(connection->getPackageName())) {
8434949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        return INVALID_OPERATION;
8444949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    }
8454949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
8464342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    SensorRecord* rec = mActiveSensors.valueFor(handle);
8474342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (rec == 0) {
8484342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        rec = new SensorRecord(connection);
8494342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        mActiveSensors.add(handle, rec);
8504342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (sensor->isVirtual()) {
8514342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            mActiveVirtualSensors.add(handle, sensor);
8523560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        }
8534342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    } else {
8544342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (rec->addConnection(connection)) {
8559a844cf78f09953145200b4074d47589257a408cAravind Akella            // this sensor is already activated, but we are adding a connection that uses it.
8569a844cf78f09953145200b4074d47589257a408cAravind Akella            // Immediately send down the last known value of the requested sensor if it's not a
8574342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            // "continuous" sensor.
8580e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ON_CHANGE) {
8599a844cf78f09953145200b4074d47589257a408cAravind Akella                // NOTE: The wake_up flag of this event may get set to
8609a844cf78f09953145200b4074d47589257a408cAravind Akella                // WAKE_UP_SENSOR_EVENT_NEEDS_ACK if this is a wake_up event.
861444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                CircularBuffer *circular_buf = mLastEventSeen.valueFor(handle);
862444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                if (circular_buf) {
863444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    sensors_event_t event;
864444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    memset(&event, 0, sizeof(event));
865444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    // It is unlikely that this buffer is empty as the sensor is already active.
866444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    // One possible corner case may be two applications activating an on-change
867444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    // sensor at the same time.
868444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    if(circular_buf->populateLastEvent(&event)) {
869444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        event.sensor = handle;
870444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        if (event.version == sizeof(sensors_event_t)) {
871444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                            if (isWakeUpSensorEvent(event) && !mWakeLockAcquired) {
872444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                                setWakeLockAcquiredLocked(true);
873444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                            }
874444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                            connection->sendEvents(&event, 1, NULL);
875444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                            if (!connection->needsWakeLock() && mWakeLockAcquired) {
876444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                                checkWakeLockStateLocked();
877444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                            }
878444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        }
8799a844cf78f09953145200b4074d47589257a408cAravind Akella                    }
880f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                }
8817c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            }
882fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
883fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
8844342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
8854342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (connection->addSensor(handle)) {
8864342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        BatteryService::enableSensor(connection->getUid(), handle);
8874342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // the sensor was added (which means it wasn't already there)
8884342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // so, see if this connection becomes active
8894342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (mActiveConnections.indexOf(connection) < 0) {
8904342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            mActiveConnections.add(connection);
8914342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
8924342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    } else {
8934342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        ALOGW("sensor %08x already enabled in connection %p (ignoring)",
8944342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            handle, connection.get());
8954342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
8964342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
897724d91d778e71c8186399f4955de14b54812b3edAravind Akella    nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
898724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (samplingPeriodNs < minDelayNs) {
899724d91d778e71c8186399f4955de14b54812b3edAravind Akella        samplingPeriodNs = minDelayNs;
900724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
901724d91d778e71c8186399f4955de14b54812b3edAravind Akella
9026c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d"
9036c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                                "rate=%" PRId64 " timeout== %" PRId64"",
904724d91d778e71c8186399f4955de14b54812b3edAravind Akella             handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs);
905724d91d778e71c8186399f4955de14b54812b3edAravind Akella
9064949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    status_t err = sensor->batch(connection.get(), handle, 0, samplingPeriodNs,
907724d91d778e71c8186399f4955de14b54812b3edAravind Akella                                 maxBatchReportLatencyNs);
9086c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
9095466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella    // Call flush() before calling activate() on the sensor. Wait for a first flush complete
9105466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella    // event before sending events on this connection. Ignore one-shot sensors which don't
9115466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella    // support flush(). Also if this sensor isn't already active, don't call flush().
9125466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella    if (err == NO_ERROR && sensor->getSensor().getReportingMode() != AREPORTING_MODE_ONE_SHOT &&
9135466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            rec->getNumConnections() > 1) {
9145466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella        connection->setFirstFlushPending(handle, true);
9154c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        status_t err_flush = sensor->flush(connection.get(), handle);
9165466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella        // Flush may return error if the underlying h/w sensor uses an older HAL.
9176c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        if (err_flush == NO_ERROR) {
9186c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            rec->addPendingFlushConnection(connection.get());
9195466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella        } else {
9205466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            connection->setFirstFlushPending(handle, false);
9214c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
9224c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
923724d91d778e71c8186399f4955de14b54812b3edAravind Akella
924724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (err == NO_ERROR) {
925724d91d778e71c8186399f4955de14b54812b3edAravind Akella        ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle);
926724d91d778e71c8186399f4955de14b54812b3edAravind Akella        err = sensor->activate(connection.get(), true);
927724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
928724d91d778e71c8186399f4955de14b54812b3edAravind Akella
9298a96955c8e14db40b16164236830fc9506a00872Aravind Akella    if (err == NO_ERROR) {
9308a96955c8e14db40b16164236830fc9506a00872Aravind Akella        connection->updateLooperRegistration(mLooper);
93118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        SensorRegistrationInfo &reg_info =
93218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex);
93318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mSensorHandle = handle;
93418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mSamplingRateUs = samplingPeriodNs/1000;
93518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mMaxReportLatencyUs = maxBatchReportLatencyNs/1000;
93618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mActivated = true;
93718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mPackageName = connection->getPackageName();
93818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        time_t rawtime = time(NULL);
93918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        struct tm * timeinfo = localtime(&rawtime);
94018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mHour = timeinfo->tm_hour;
94118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mMin = timeinfo->tm_min;
94218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mSec = timeinfo->tm_sec;
94318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        mNextSensorRegIndex = (mNextSensorRegIndex + 1) % SENSOR_REGISTRATIONS_BUF_SIZE;
94456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    }
94556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
9464342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (err != NO_ERROR) {
947724d91d778e71c8186399f4955de14b54812b3edAravind Akella        // batch/activate has failed, reset our state.
948ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        cleanupWithoutDisableLocked(connection, handle);
9494342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
950fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return err;
951fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
952fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
953fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::disable(const sp<SensorEventConnection>& connection,
954fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        int handle)
955fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
95650df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian    if (mInitCheck != NO_ERROR)
95750df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian        return mInitCheck;
95850df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
959ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    Mutex::Autolock _l(mLock);
960ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    status_t err = cleanupWithoutDisableLocked(connection, handle);
9614342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (err == NO_ERROR) {
9624342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        SensorInterface* sensor = mSensorMap.valueFor(handle);
9634342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        err = sensor ? sensor->activate(connection.get(), false) : status_t(BAD_VALUE);
96418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella
96518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    }
96618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    if (err == NO_ERROR) {
96718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        SensorRegistrationInfo &reg_info =
96818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex);
96918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mActivated = false;
97018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mPackageName= connection->getPackageName();
97118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mSensorHandle = handle;
97218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        time_t rawtime = time(NULL);
97318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        struct tm * timeinfo = localtime(&rawtime);
97418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mHour = timeinfo->tm_hour;
97518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mMin = timeinfo->tm_min;
97618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        reg_info.mSec = timeinfo->tm_sec;
97718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        mNextSensorRegIndex = (mNextSensorRegIndex + 1) % SENSOR_REGISTRATIONS_BUF_SIZE;
9784342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
9794342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    return err;
9804342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh}
9814342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
982ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisable(
983ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        const sp<SensorEventConnection>& connection, int handle) {
984fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    Mutex::Autolock _l(mLock);
985ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    return cleanupWithoutDisableLocked(connection, handle);
986ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian}
987ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian
988ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisableLocked(
989ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        const sp<SensorEventConnection>& connection, int handle) {
990fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    SensorRecord* rec = mActiveSensors.valueFor(handle);
991fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (rec) {
992fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        // see if this connection becomes inactive
993787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian        if (connection->removeSensor(handle)) {
994787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian            BatteryService::disableSensor(connection->getUid(), handle);
995787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian        }
996fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        if (connection->hasAnySensor() == false) {
9978a96955c8e14db40b16164236830fc9506a00872Aravind Akella            connection->updateLooperRegistration(mLooper);
998fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            mActiveConnections.remove(connection);
999fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
1000fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        // see if this sensor becomes inactive
1001fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        if (rec->removeConnection(connection)) {
1002fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            mActiveSensors.removeItem(handle);
1003f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            mActiveVirtualSensors.removeItem(handle);
1004fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            delete rec;
1005fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
10064342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        return NO_ERROR;
10077c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    }
10084342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    return BAD_VALUE;
1009fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1010fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
10117c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianstatus_t SensorService::setEventRate(const sp<SensorEventConnection>& connection,
1012b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        int handle, nsecs_t ns, const String16& opPackageName)
1013fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
101450df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian    if (mInitCheck != NO_ERROR)
101550df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian        return mInitCheck;
101650df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
1017ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian    SensorInterface* sensor = mSensorMap.valueFor(handle);
1018ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian    if (!sensor)
1019ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian        return BAD_VALUE;
1020ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian
1021b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (!canAccessSensor(sensor->getSensor(), "Tried configuring", opPackageName)) {
1022700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return BAD_VALUE;
1023700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
1024700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
10251cd700015318727d6d42236ab6274f1949fb08baMathias Agopian    if (ns < 0)
10261cd700015318727d6d42236ab6274f1949fb08baMathias Agopian        return BAD_VALUE;
10271cd700015318727d6d42236ab6274f1949fb08baMathias Agopian
102862569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian    nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
102962569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian    if (ns < minDelayNs) {
103062569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian        ns = minDelayNs;
1031ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian    }
1032ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian
1033f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    return sensor->setDelay(connection.get(), handle, ns);
1034fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1035fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1036b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslavstatus_t SensorService::flushSensor(const sp<SensorEventConnection>& connection,
1037b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        const String16& opPackageName) {
1038700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    if (mInitCheck != NO_ERROR) return mInitCheck;
10399e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    SensorDevice& dev(SensorDevice::getInstance());
10409e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    const int halVersion = dev.getHalDeviceVersion();
10419e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    status_t err(NO_ERROR);
10429e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    Mutex::Autolock _l(mLock);
10439e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    // Loop through all sensors for this connection and call flush on each of them.
10449e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    for (size_t i = 0; i < connection->mSensorInfo.size(); ++i) {
10459e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        const int handle = connection->mSensorInfo.keyAt(i);
10469e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        SensorInterface* sensor = mSensorMap.valueFor(handle);
10479e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
10489e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            ALOGE("flush called on a one-shot sensor");
10499e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            err = INVALID_OPERATION;
10509e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            continue;
10519e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        }
10528493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        if (halVersion <= SENSORS_DEVICE_API_VERSION_1_0 || isVirtualSensor(handle)) {
10539e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            // For older devices just increment pending flush count which will send a trivial
10549e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            // flush complete event.
10558a96955c8e14db40b16164236830fc9506a00872Aravind Akella            connection->incrementPendingFlushCount(handle);
10569e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        } else {
1057b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            if (!canAccessSensor(sensor->getSensor(), "Tried flushing", opPackageName)) {
1058b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                err = INVALID_OPERATION;
1059b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                continue;
1060b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            }
10619e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            status_t err_flush = sensor->flush(connection.get(), handle);
10629e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            if (err_flush == NO_ERROR) {
10639e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella                SensorRecord* rec = mActiveSensors.valueFor(handle);
10649e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella                if (rec != NULL) rec->addPendingFlushConnection(connection);
10659e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            }
10669e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            err = (err_flush != NO_ERROR) ? err_flush : err;
10679e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        }
10686c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    }
10699e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    return err;
1070700180487ffec09d9df1657b018a7caadac24b75Aravind Akella}
1071700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
1072b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslavbool SensorService::canAccessSensor(const Sensor& sensor, const char* operation,
1073b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        const String16& opPackageName) {
1074b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    const String8& requiredPermission = sensor.getRequiredPermission();
1075700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
1076b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (requiredPermission.length() <= 0) {
1077700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return true;
1078b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    }
1079b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav
1080b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    bool hasPermission = false;
1081b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav
1082b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    // Runtime permissions can't use the cache as they may change.
1083b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (sensor.isRequiredPermissionRuntime()) {
1084b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        hasPermission = checkPermission(String16(requiredPermission),
1085b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                IPCThreadState::self()->getCallingPid(), IPCThreadState::self()->getCallingUid());
1086700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    } else {
1087b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        hasPermission = PermissionCache::checkCallingPermission(String16(requiredPermission));
1088b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    }
1089b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav
1090b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (!hasPermission) {
1091b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        ALOGE("%s a sensor (%s) without holding its required permission: %s",
1092b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                operation, sensor.getName().string(), sensor.getRequiredPermission().string());
1093700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return false;
1094700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
1095b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav
1096b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    const int32_t opCode = sensor.getRequiredAppOp();
1097b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (opCode >= 0) {
1098b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        AppOpsManager appOps;
1099b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        if (appOps.noteOp(opCode, IPCThreadState::self()->getCallingUid(), opPackageName)
1100b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                        != AppOpsManager::MODE_ALLOWED) {
1101b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            ALOGE("%s a sensor (%s) without enabled required app op: %D",
1102b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                    operation, sensor.getName().string(), opCode);
1103b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            return false;
1104b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        }
1105b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    }
1106b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav
1107b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    return true;
1108700180487ffec09d9df1657b018a7caadac24b75Aravind Akella}
1109700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
11109a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockState() {
11119a844cf78f09953145200b4074d47589257a408cAravind Akella    Mutex::Autolock _l(mLock);
11129a844cf78f09953145200b4074d47589257a408cAravind Akella    checkWakeLockStateLocked();
11139a844cf78f09953145200b4074d47589257a408cAravind Akella}
11149a844cf78f09953145200b4074d47589257a408cAravind Akella
11159a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockStateLocked() {
11169a844cf78f09953145200b4074d47589257a408cAravind Akella    if (!mWakeLockAcquired) {
11179a844cf78f09953145200b4074d47589257a408cAravind Akella        return;
11189a844cf78f09953145200b4074d47589257a408cAravind Akella    }
11199a844cf78f09953145200b4074d47589257a408cAravind Akella    bool releaseLock = true;
11209a844cf78f09953145200b4074d47589257a408cAravind Akella    for (size_t i=0 ; i<mActiveConnections.size() ; i++) {
11219a844cf78f09953145200b4074d47589257a408cAravind Akella        sp<SensorEventConnection> connection(mActiveConnections[i].promote());
11229a844cf78f09953145200b4074d47589257a408cAravind Akella        if (connection != 0) {
11239a844cf78f09953145200b4074d47589257a408cAravind Akella            if (connection->needsWakeLock()) {
11249a844cf78f09953145200b4074d47589257a408cAravind Akella                releaseLock = false;
11259a844cf78f09953145200b4074d47589257a408cAravind Akella                break;
11269a844cf78f09953145200b4074d47589257a408cAravind Akella            }
11279a844cf78f09953145200b4074d47589257a408cAravind Akella        }
11289a844cf78f09953145200b4074d47589257a408cAravind Akella    }
11299a844cf78f09953145200b4074d47589257a408cAravind Akella    if (releaseLock) {
1130b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        setWakeLockAcquiredLocked(false);
1131b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    }
1132b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
1133b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
1134b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::sendEventsFromCache(const sp<SensorEventConnection>& connection) {
1135b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    Mutex::Autolock _l(mLock);
1136b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    connection->writeToSocketFromCache();
1137b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    if (connection->needsWakeLock()) {
1138b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        setWakeLockAcquiredLocked(true);
1139b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    }
1140b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
1141b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
1142b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::populateActiveConnections(
1143b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        SortedVector< sp<SensorEventConnection> >* activeConnections) {
1144b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    Mutex::Autolock _l(mLock);
1145b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    for (size_t i=0 ; i < mActiveConnections.size(); ++i) {
1146b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        sp<SensorEventConnection> connection(mActiveConnections[i].promote());
1147b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        if (connection != 0) {
1148b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            activeConnections->add(connection);
1149b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        }
11509a844cf78f09953145200b4074d47589257a408cAravind Akella    }
11519a844cf78f09953145200b4074d47589257a408cAravind Akella}
11526c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
11534949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akellabool SensorService::isWhiteListedPackage(const String8& packageName) {
1154841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    return (packageName.contains(mWhiteListedPackage.string()));
11554949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella}
11564949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
1157444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akellaint SensorService::getNumEventsForSensorType(int sensor_event_type) {
1158444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    switch (sensor_event_type) {
1159444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        case SENSOR_TYPE_ROTATION_VECTOR:
1160444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
1161444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            return 5;
1162444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella
1163444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
1164444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
1165444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            return 6;
1166444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella
1167444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        case SENSOR_TYPE_GAME_ROTATION_VECTOR:
1168444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            return 4;
1169444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella
1170444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        case SENSOR_TYPE_SIGNIFICANT_MOTION:
1171444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        case SENSOR_TYPE_STEP_DETECTOR:
1172444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        case SENSOR_TYPE_STEP_COUNTER:
1173444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            return 1;
1174444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella
1175444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella         default:
1176444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            return 3;
1177444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    }
1178444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella}
1179444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella
1180fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// ---------------------------------------------------------------------------
1181fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorRecord::SensorRecord(
1182fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        const sp<SensorEventConnection>& connection)
1183fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
1184fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    mConnections.add(connection);
1185fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1186fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
11877c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianbool SensorService::SensorRecord::addConnection(
1188fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        const sp<SensorEventConnection>& connection)
1189fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
1190fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (mConnections.indexOf(connection) < 0) {
1191fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        mConnections.add(connection);
11927c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian        return true;
1193fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
11947c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    return false;
1195fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1196fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1197fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::SensorRecord::removeConnection(
1198fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        const wp<SensorEventConnection>& connection)
1199fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
1200fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    ssize_t index = mConnections.indexOf(connection);
1201fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (index >= 0) {
1202fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        mConnections.removeItemsAt(index, 1);
1203fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
12046c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    // Remove this connections from the queue of flush() calls made on this sensor.
12056c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    for (Vector< wp<SensorEventConnection> >::iterator it =
12066c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            mPendingFlushConnections.begin(); it != mPendingFlushConnections.end();) {
12078a96955c8e14db40b16164236830fc9506a00872Aravind Akella
12086c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        if (it->unsafe_get() == connection.unsafe_get()) {
12096c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            it = mPendingFlushConnections.erase(it);
12106c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        } else {
12116c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            ++it;
12126c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        }
12136c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    }
1214fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return mConnections.size() ? false : true;
1215fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1216fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
12176c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akellavoid SensorService::SensorRecord::addPendingFlushConnection(
12186c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        const sp<SensorEventConnection>& connection) {
12196c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    mPendingFlushConnections.add(connection);
12206c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella}
12216c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
12226c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akellavoid SensorService::SensorRecord::removeFirstPendingFlushConnection() {
12236c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    if (mPendingFlushConnections.size() > 0) {
12246c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        mPendingFlushConnections.removeAt(0);
12256c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    }
12266c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella}
12276c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
12286c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind AkellaSensorService::SensorEventConnection *
12296c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind AkellaSensorService::SensorRecord::getFirstPendingFlushConnection() {
12306c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella   if (mPendingFlushConnections.size() > 0) {
12316c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        return mPendingFlushConnections[0].unsafe_get();
12326c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    }
12336c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    return NULL;
12346c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella}
12356c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
12364949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akellavoid SensorService::SensorRecord::clearAllPendingFlushConnections() {
12374949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    mPendingFlushConnections.clear();
12384949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella}
12394949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
124018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella
124118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella// ---------------------------------------------------------------------------
124218d6d51a00897988e3347b130f533e9ffdd8c365Aravind AkellaSensorService::TrimmedSensorEvent::TrimmedSensorEvent(int sensorType) {
124318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    mTimestamp = -1;
124418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    const int numData = SensorService::getNumEventsForSensorType(sensorType);
124518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    if (sensorType == SENSOR_TYPE_STEP_COUNTER) {
124618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        mStepCounter = 0;
124718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    } else {
124818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        mData = new float[numData];
124918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        for (int i = 0; i < numData; ++i) {
125018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            mData[i] = -1.0;
125118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        }
125218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    }
125318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    mHour = mMin = mSec = INT32_MIN;
125418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella}
125518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella
125618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akellabool SensorService::TrimmedSensorEvent::isSentinel(const TrimmedSensorEvent& event) {
125718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    return (event.mHour == INT32_MIN && event.mMin == INT32_MIN && event.mSec == INT32_MIN);
125818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella}
1259444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella// --------------------------------------------------------------------------
1260444f2675728dde36378beb8e67a94f86ebf1ca46Aravind AkellaSensorService::CircularBuffer::CircularBuffer(int sensor_event_type) {
1261444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    mNextInd = 0;
126218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    mBufSize = CIRCULAR_BUF_SIZE;
126318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    if (sensor_event_type == SENSOR_TYPE_STEP_COUNTER ||
126418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            sensor_event_type == SENSOR_TYPE_SIGNIFICANT_MOTION ||
126518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            sensor_event_type == SENSOR_TYPE_ACCELEROMETER) {
126618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        mBufSize = CIRCULAR_BUF_SIZE * 5;
126718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    }
126818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    mTrimmedSensorEventArr = new TrimmedSensorEvent *[mBufSize];
1269444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    mSensorType = sensor_event_type;
127018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    for (int i = 0; i < mBufSize; ++i) {
127118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        mTrimmedSensorEventArr[i] = new TrimmedSensorEvent(mSensorType);
1272444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    }
1273444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella}
1274444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella
1275444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akellavoid SensorService::CircularBuffer::addEvent(const sensors_event_t& sensor_event) {
1276444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    TrimmedSensorEvent *curr_event = mTrimmedSensorEventArr[mNextInd];
1277444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    curr_event->mTimestamp = sensor_event.timestamp;
1278444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    if (mSensorType == SENSOR_TYPE_STEP_COUNTER) {
1279444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        curr_event->mStepCounter = sensor_event.u64.step_counter;
1280444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    } else {
1281444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        memcpy(curr_event->mData, sensor_event.data,
1282444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                 sizeof(float) * SensorService::getNumEventsForSensorType(mSensorType));
1283444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    }
1284444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    time_t rawtime = time(NULL);
1285444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    struct tm * timeinfo = localtime(&rawtime);
1286444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    curr_event->mHour = timeinfo->tm_hour;
1287444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    curr_event->mMin = timeinfo->tm_min;
1288444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    curr_event->mSec = timeinfo->tm_sec;
128918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    mNextInd = (mNextInd + 1) % mBufSize;
1290444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella}
1291444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella
1292444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akellavoid SensorService::CircularBuffer::printBuffer(String8& result) const {
1293444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    const int numData = SensorService::getNumEventsForSensorType(mSensorType);
1294444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    int i = mNextInd, eventNum = 1;
129518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    result.appendFormat("last %d events = < ", mBufSize);
1296444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    do {
129718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        if (TrimmedSensorEvent::isSentinel(*mTrimmedSensorEventArr[i])) {
1298444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            // Sentinel, ignore.
129918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            i = (i + 1) % mBufSize;
1300444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            continue;
1301444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        }
1302444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        result.appendFormat("%d) ", eventNum++);
1303444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        if (mSensorType == SENSOR_TYPE_STEP_COUNTER) {
1304444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            result.appendFormat("%llu,", mTrimmedSensorEventArr[i]->mStepCounter);
1305444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        } else {
1306444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            for (int j = 0; j < numData; ++j) {
1307444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                result.appendFormat("%5.1f,", mTrimmedSensorEventArr[i]->mData[j]);
1308444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            }
1309444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        }
1310444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        result.appendFormat("%lld %02d:%02d:%02d ", mTrimmedSensorEventArr[i]->mTimestamp,
1311444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                mTrimmedSensorEventArr[i]->mHour, mTrimmedSensorEventArr[i]->mMin,
1312444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                mTrimmedSensorEventArr[i]->mSec);
131318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        i = (i + 1) % mBufSize;
1314444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    } while (i != mNextInd);
1315444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    result.appendFormat(">\n");
1316444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella}
1317444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella
1318444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akellabool SensorService::CircularBuffer::populateLastEvent(sensors_event_t *event) {
131918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    int lastEventInd = (mNextInd - 1 + mBufSize) % mBufSize;
1320444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    // Check if the buffer is empty.
132118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    if (TrimmedSensorEvent::isSentinel(*mTrimmedSensorEventArr[lastEventInd])) {
1322444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        return false;
1323444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    }
1324444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    event->version = sizeof(sensors_event_t);
1325444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    event->type = mSensorType;
1326444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    event->timestamp = mTrimmedSensorEventArr[lastEventInd]->mTimestamp;
1327444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    if (mSensorType == SENSOR_TYPE_STEP_COUNTER) {
1328444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella          event->u64.step_counter = mTrimmedSensorEventArr[lastEventInd]->mStepCounter;
1329444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    } else {
1330444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        memcpy(event->data, mTrimmedSensorEventArr[lastEventInd]->mData,
1331444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                 sizeof(float) * SensorService::getNumEventsForSensorType(mSensorType));
1332444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    }
1333444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    return true;
1334444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella}
1335444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella
1336444f2675728dde36378beb8e67a94f86ebf1ca46Aravind AkellaSensorService::CircularBuffer::~CircularBuffer() {
133718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    for (int i = 0; i < mBufSize; ++i) {
1338444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        delete mTrimmedSensorEventArr[i];
1339444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    }
1340444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    delete [] mTrimmedSensorEventArr;
1341444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella}
1342444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella
1343fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// ---------------------------------------------------------------------------
1344fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1345fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorEventConnection::SensorEventConnection(
1346b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        const sp<SensorService>& service, uid_t uid, String8 packageName, bool isDataInjectionMode,
1347b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        const String16& opPackageName)
13488a96955c8e14db40b16164236830fc9506a00872Aravind Akella    : mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false),
1349b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav      mDead(false), mDataInjectionMode(isDataInjectionMode), mEventCache(NULL),
1350b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav      mCacheSize(0), mMaxCacheSize(0), mPackageName(packageName), mOpPackageName(opPackageName) {
13515466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella    mChannel = new BitTube(mService->mSocketBufferSize);
135256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#if DEBUG_CONNECTIONS
135356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
1354e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella    mTotalAcksNeeded = mTotalAcksReceived = 0;
135556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#endif
1356fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1357fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
135856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind AkellaSensorService::SensorEventConnection::~SensorEventConnection() {
1359a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block    ALOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this);
1360e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella    mService->cleanupConnection(this);
136156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    if (mEventCache != NULL) {
136256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        delete mEventCache;
136356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    }
1364fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1365fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
136656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellavoid SensorService::SensorEventConnection::onFirstRef() {
136756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    LooperCallback::onFirstRef();
1368fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1369fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
13709a844cf78f09953145200b4074d47589257a408cAravind Akellabool SensorService::SensorEventConnection::needsWakeLock() {
13719a844cf78f09953145200b4074d47589257a408cAravind Akella    Mutex::Autolock _l(mConnectionLock);
13728a96955c8e14db40b16164236830fc9506a00872Aravind Akella    return !mDead && mWakeLockRefCount > 0;
13739a844cf78f09953145200b4074d47589257a408cAravind Akella}
13749a844cf78f09953145200b4074d47589257a408cAravind Akella
1375b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::SensorEventConnection::resetWakeLockRefCount() {
1376b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    Mutex::Autolock _l(mConnectionLock);
1377b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    mWakeLockRefCount = 0;
1378b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
1379b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
13804c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akellavoid SensorService::SensorEventConnection::dump(String8& result) {
13814c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    Mutex::Autolock _l(mConnectionLock);
1382a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    result.appendFormat("Operating Mode: %s\n", mDataInjectionMode ? "DATA_INJECTION" : "NORMAL");
138318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    result.appendFormat("\t %s | WakeLockRefCount %d | uid %d | cache size %d | "
138418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            "max cache size %d\n", mPackageName.string(), mWakeLockRefCount, mUid, mCacheSize,
138518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            mMaxCacheSize);
13864c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
13874c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        const FlushInfo& flushInfo = mSensorInfo.valueAt(i);
13880ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella        result.appendFormat("\t %s 0x%08x | status: %s | pending flush events %d \n",
13894c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                            mService->getSensorName(mSensorInfo.keyAt(i)).string(),
13906c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                            mSensorInfo.keyAt(i),
13914c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                            flushInfo.mFirstFlushPending ? "First flush pending" :
13924c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                                                           "active",
13930ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella                            flushInfo.mPendingFlushEventsToSend);
13940ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella    }
139556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#if DEBUG_CONNECTIONS
13960ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella    result.appendFormat("\t events recvd: %d | sent %d | cache %d | dropped %d |"
13970ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella            " total_acks_needed %d | total_acks_recvd %d\n",
13980ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella            mEventsReceived,
13990ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella            mEventsSent,
14000ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella            mEventsSentFromCache,
14010ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella            mEventsReceived - (mEventsSentFromCache + mEventsSent + mCacheSize),
14020ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella            mTotalAcksNeeded,
14030ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella            mTotalAcksReceived);
140456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#endif
14054c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella}
14064c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
14077c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianbool SensorService::SensorEventConnection::addSensor(int32_t handle) {
140871d7a5c289c6ef6b5fc86dd4784a075ca6470e38Mathias Agopian    Mutex::Autolock _l(mConnectionLock);
1409b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (!canAccessSensor(mService->getSensorFromHandle(handle),
1410b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            "Tried adding", mOpPackageName)) {
1411700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return false;
1412700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
14134c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    if (mSensorInfo.indexOfKey(handle) < 0) {
14144c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        mSensorInfo.add(handle, FlushInfo());
14157c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian        return true;
1416fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
14177c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    return false;
1418fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1419fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
14207c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianbool SensorService::SensorEventConnection::removeSensor(int32_t handle) {
142171d7a5c289c6ef6b5fc86dd4784a075ca6470e38Mathias Agopian    Mutex::Autolock _l(mConnectionLock);
14224c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    if (mSensorInfo.removeItem(handle) >= 0) {
14237c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian        return true;
14247c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    }
14257c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    return false;
1426fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1427fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1428fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
142971d7a5c289c6ef6b5fc86dd4784a075ca6470e38Mathias Agopian    Mutex::Autolock _l(mConnectionLock);
14304c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    return mSensorInfo.indexOfKey(handle) >= 0;
1431fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1432fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1433fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::SensorEventConnection::hasAnySensor() const {
143471d7a5c289c6ef6b5fc86dd4784a075ca6470e38Mathias Agopian    Mutex::Autolock _l(mConnectionLock);
14357c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    return mSensorInfo.size() ? true : false;
14367c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian}
14377c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian
14388493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akellabool SensorService::SensorEventConnection::hasOneShotSensors() const {
14398493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella    Mutex::Autolock _l(mConnectionLock);
14408493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
14418493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        const int handle = mSensorInfo.keyAt(i);
14428493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        if (mService->getSensorFromHandle(handle).getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
14438493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            return true;
14448493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        }
14458493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella    }
14468493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella    return false;
14478493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella}
14488493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella
14494949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind AkellaString8 SensorService::SensorEventConnection::getPackageName() const {
14504949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    return mPackageName;
14514949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella}
14524949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
14534c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akellavoid SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle,
14544c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                                bool value) {
14554c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    Mutex::Autolock _l(mConnectionLock);
14564c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    ssize_t index = mSensorInfo.indexOfKey(handle);
14574c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    if (index >= 0) {
14584c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
14594c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        flushInfo.mFirstFlushPending = value;
14604c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
14614c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella}
14624c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
14638a96955c8e14db40b16164236830fc9506a00872Aravind Akellavoid SensorService::SensorEventConnection::updateLooperRegistration(const sp<Looper>& looper) {
14648a96955c8e14db40b16164236830fc9506a00872Aravind Akella    Mutex::Autolock _l(mConnectionLock);
14658a96955c8e14db40b16164236830fc9506a00872Aravind Akella    updateLooperRegistrationLocked(looper);
14668a96955c8e14db40b16164236830fc9506a00872Aravind Akella}
14678a96955c8e14db40b16164236830fc9506a00872Aravind Akella
14688a96955c8e14db40b16164236830fc9506a00872Aravind Akellavoid SensorService::SensorEventConnection::updateLooperRegistrationLocked(
14698a96955c8e14db40b16164236830fc9506a00872Aravind Akella        const sp<Looper>& looper) {
1470a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    bool isConnectionActive = (mSensorInfo.size() > 0 && !mDataInjectionMode) ||
1471a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella                              mDataInjectionMode;
14728a96955c8e14db40b16164236830fc9506a00872Aravind Akella    // If all sensors are unregistered OR Looper has encountered an error, we
14738a96955c8e14db40b16164236830fc9506a00872Aravind Akella    // can remove the Fd from the Looper if it has been previously added.
14748a96955c8e14db40b16164236830fc9506a00872Aravind Akella    if (!isConnectionActive || mDead) {
14758a96955c8e14db40b16164236830fc9506a00872Aravind Akella        if (mHasLooperCallbacks) {
14768a96955c8e14db40b16164236830fc9506a00872Aravind Akella            ALOGD_IF(DEBUG_CONNECTIONS, "%p removeFd fd=%d", this, mChannel->getSendFd());
14778a96955c8e14db40b16164236830fc9506a00872Aravind Akella            looper->removeFd(mChannel->getSendFd());
14788a96955c8e14db40b16164236830fc9506a00872Aravind Akella            mHasLooperCallbacks = false;
14798a96955c8e14db40b16164236830fc9506a00872Aravind Akella        }
14808a96955c8e14db40b16164236830fc9506a00872Aravind Akella        return;
14818a96955c8e14db40b16164236830fc9506a00872Aravind Akella    }
14828a96955c8e14db40b16164236830fc9506a00872Aravind Akella
14838a96955c8e14db40b16164236830fc9506a00872Aravind Akella    int looper_flags = 0;
14848a96955c8e14db40b16164236830fc9506a00872Aravind Akella    if (mCacheSize > 0) looper_flags |= ALOOPER_EVENT_OUTPUT;
1485a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    if (mDataInjectionMode) looper_flags |= ALOOPER_EVENT_INPUT;
14868a96955c8e14db40b16164236830fc9506a00872Aravind Akella    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
14878a96955c8e14db40b16164236830fc9506a00872Aravind Akella        const int handle = mSensorInfo.keyAt(i);
14888a96955c8e14db40b16164236830fc9506a00872Aravind Akella        if (mService->getSensorFromHandle(handle).isWakeUpSensor()) {
14898a96955c8e14db40b16164236830fc9506a00872Aravind Akella            looper_flags |= ALOOPER_EVENT_INPUT;
14908a96955c8e14db40b16164236830fc9506a00872Aravind Akella            break;
14918a96955c8e14db40b16164236830fc9506a00872Aravind Akella        }
14928a96955c8e14db40b16164236830fc9506a00872Aravind Akella    }
14938a96955c8e14db40b16164236830fc9506a00872Aravind Akella    // If flags is still set to zero, we don't need to add this fd to the Looper, if
14948a96955c8e14db40b16164236830fc9506a00872Aravind Akella    // the fd has already been added, remove it. This is likely to happen when ALL the
14958a96955c8e14db40b16164236830fc9506a00872Aravind Akella    // events stored in the cache have been sent to the corresponding app.
14968a96955c8e14db40b16164236830fc9506a00872Aravind Akella    if (looper_flags == 0) {
14978a96955c8e14db40b16164236830fc9506a00872Aravind Akella        if (mHasLooperCallbacks) {
14988a96955c8e14db40b16164236830fc9506a00872Aravind Akella            ALOGD_IF(DEBUG_CONNECTIONS, "removeFd fd=%d", mChannel->getSendFd());
14998a96955c8e14db40b16164236830fc9506a00872Aravind Akella            looper->removeFd(mChannel->getSendFd());
15008a96955c8e14db40b16164236830fc9506a00872Aravind Akella            mHasLooperCallbacks = false;
15018a96955c8e14db40b16164236830fc9506a00872Aravind Akella        }
15028a96955c8e14db40b16164236830fc9506a00872Aravind Akella        return;
15038a96955c8e14db40b16164236830fc9506a00872Aravind Akella    }
15048a96955c8e14db40b16164236830fc9506a00872Aravind Akella    // Add the file descriptor to the Looper for receiving acknowledegments if the app has
15058a96955c8e14db40b16164236830fc9506a00872Aravind Akella    // registered for wake-up sensors OR for sending events in the cache.
15068a96955c8e14db40b16164236830fc9506a00872Aravind Akella    int ret = looper->addFd(mChannel->getSendFd(), 0, looper_flags, this, NULL);
15078a96955c8e14db40b16164236830fc9506a00872Aravind Akella    if (ret == 1) {
15088a96955c8e14db40b16164236830fc9506a00872Aravind Akella        ALOGD_IF(DEBUG_CONNECTIONS, "%p addFd fd=%d", this, mChannel->getSendFd());
15098a96955c8e14db40b16164236830fc9506a00872Aravind Akella        mHasLooperCallbacks = true;
15108a96955c8e14db40b16164236830fc9506a00872Aravind Akella    } else {
15118a96955c8e14db40b16164236830fc9506a00872Aravind Akella        ALOGE("Looper::addFd failed ret=%d fd=%d", ret, mChannel->getSendFd());
15128a96955c8e14db40b16164236830fc9506a00872Aravind Akella    }
15138a96955c8e14db40b16164236830fc9506a00872Aravind Akella}
15148a96955c8e14db40b16164236830fc9506a00872Aravind Akella
15158a96955c8e14db40b16164236830fc9506a00872Aravind Akellavoid SensorService::SensorEventConnection::incrementPendingFlushCount(int32_t handle) {
15168a96955c8e14db40b16164236830fc9506a00872Aravind Akella    Mutex::Autolock _l(mConnectionLock);
15178a96955c8e14db40b16164236830fc9506a00872Aravind Akella    ssize_t index = mSensorInfo.indexOfKey(handle);
15188a96955c8e14db40b16164236830fc9506a00872Aravind Akella    if (index >= 0) {
15198a96955c8e14db40b16164236830fc9506a00872Aravind Akella        FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
15208a96955c8e14db40b16164236830fc9506a00872Aravind Akella        flushInfo.mPendingFlushEventsToSend++;
15218a96955c8e14db40b16164236830fc9506a00872Aravind Akella    }
15228a96955c8e14db40b16164236830fc9506a00872Aravind Akella}
15238a96955c8e14db40b16164236830fc9506a00872Aravind Akella
1524fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::SensorEventConnection::sendEvents(
15250ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella        sensors_event_t const* buffer, size_t numEvents,
15268493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        sensors_event_t* scratch,
15278493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        SensorEventConnection const * const * mapFlushEventsToConnections) {
1528cf51001dbf28e9885fcacd4048902f1c75768fe9Mathias Agopian    // filter out events not for this connection
1529b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    int count = 0;
15309a844cf78f09953145200b4074d47589257a408cAravind Akella    Mutex::Autolock _l(mConnectionLock);
15313560fb24b668675627934356f210d84d19bf4e56Mathias Agopian    if (scratch) {
15323560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        size_t i=0;
15333560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        while (i<numEvents) {
15346c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            int32_t sensor_handle = buffer[i].sensor;
1535724d91d778e71c8186399f4955de14b54812b3edAravind Akella            if (buffer[i].type == SENSOR_TYPE_META_DATA) {
1536724d91d778e71c8186399f4955de14b54812b3edAravind Akella                ALOGD_IF(DEBUG_CONNECTIONS, "flush complete event sensor==%d ",
15379e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella                        buffer[i].meta_data.sensor);
15388a96955c8e14db40b16164236830fc9506a00872Aravind Akella                // Setting sensor_handle to the correct sensor to ensure the sensor events per
15398a96955c8e14db40b16164236830fc9506a00872Aravind Akella                // connection are filtered correctly.  buffer[i].sensor is zero for meta_data
15408a96955c8e14db40b16164236830fc9506a00872Aravind Akella                // events.
15416c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                sensor_handle = buffer[i].meta_data.sensor;
1542724d91d778e71c8186399f4955de14b54812b3edAravind Akella            }
15436c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            ssize_t index = mSensorInfo.indexOfKey(sensor_handle);
154456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            // Check if this connection has registered for this sensor. If not continue to the
154556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            // next sensor_event.
154656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            if (index < 0) {
154756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                ++i;
154856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                continue;
15494c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
155056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
155156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
15526c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            // Check if there is a pending flush_complete event for this sensor on this connection.
15538493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            if (buffer[i].type == SENSOR_TYPE_META_DATA && flushInfo.mFirstFlushPending == true &&
15548493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    this == mapFlushEventsToConnections[i]) {
15558493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                flushInfo.mFirstFlushPending = false;
15568493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                ALOGD_IF(DEBUG_CONNECTIONS, "First flush event for sensor==%d ",
15578493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                        buffer[i].meta_data.sensor);
15588493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                ++i;
15598493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                continue;
156056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            }
156156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
156256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            // If there is a pending flush complete event for this sensor on this connection,
156356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            // ignore the event and proceed to the next.
156456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            if (flushInfo.mFirstFlushPending) {
156556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                ++i;
156656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                continue;
15673560fb24b668675627934356f210d84d19bf4e56Mathias Agopian            }
156856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
156956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            do {
15708493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                // Keep copying events into the scratch buffer as long as they are regular
15718493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                // sensor_events are from the same sensor_handle OR they are flush_complete_events
15728493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                // from the same sensor_handle AND the current connection is mapped to the
15738493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                // corresponding flush_complete_event.
157456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                if (buffer[i].type == SENSOR_TYPE_META_DATA) {
15758493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    if (this == mapFlushEventsToConnections[i]) {
157656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                        scratch[count++] = buffer[i];
157756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                    }
157856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                    ++i;
157956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                } else {
158056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                    // Regular sensor event, just copy it to the scratch buffer.
158156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                    scratch[count++] = buffer[i++];
158256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                }
15838493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            } while ((i<numEvents) && ((buffer[i].sensor == sensor_handle &&
15848493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                                        buffer[i].type != SENSOR_TYPE_META_DATA) ||
158556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                                       (buffer[i].type == SENSOR_TYPE_META_DATA  &&
15866c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                                        buffer[i].meta_data.sensor == sensor_handle)));
1587cf51001dbf28e9885fcacd4048902f1c75768fe9Mathias Agopian        }
15883560fb24b668675627934356f210d84d19bf4e56Mathias Agopian    } else {
15893560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        scratch = const_cast<sensors_event_t *>(buffer);
15903560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        count = numEvents;
1591cf51001dbf28e9885fcacd4048902f1c75768fe9Mathias Agopian    }
1592fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
15936c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    sendPendingFlushEventsLocked();
159456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    // Early return if there are no events for this connection.
159556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    if (count == 0) {
159656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        return status_t(NO_ERROR);
159756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    }
159856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
159956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#if DEBUG_CONNECTIONS
160056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella     mEventsReceived += count;
160156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#endif
160256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    if (mCacheSize != 0) {
160356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        // There are some events in the cache which need to be sent first. Copy this buffer to
160456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        // the end of cache.
160556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        if (mCacheSize + count <= mMaxCacheSize) {
160656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            memcpy(&mEventCache[mCacheSize], scratch, count * sizeof(sensors_event_t));
160756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            mCacheSize += count;
160856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        } else {
16096c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            // Check if any new sensors have registered on this connection which may have increased
16106c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            // the max cache size that is desired.
16116c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            if (mCacheSize + count < computeMaxCacheSizeLocked()) {
16126c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                reAllocateCacheLocked(scratch, count);
16136c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                return status_t(NO_ERROR);
16146c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            }
161556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            // Some events need to be dropped.
161656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            int remaningCacheSize = mMaxCacheSize - mCacheSize;
161756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            if (remaningCacheSize != 0) {
161856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                memcpy(&mEventCache[mCacheSize], scratch,
161956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                                                remaningCacheSize * sizeof(sensors_event_t));
162056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            }
162156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            int numEventsDropped = count - remaningCacheSize;
162256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            countFlushCompleteEventsLocked(mEventCache, numEventsDropped);
162356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            // Drop the first "numEventsDropped" in the cache.
162456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            memmove(mEventCache, &mEventCache[numEventsDropped],
162556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                    (mCacheSize - numEventsDropped) * sizeof(sensors_event_t));
162656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
162756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            // Copy the remainingEvents in scratch buffer to the end of cache.
162856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            memcpy(&mEventCache[mCacheSize - numEventsDropped], scratch + remaningCacheSize,
162956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                                            numEventsDropped * sizeof(sensors_event_t));
163056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        }
163156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        return status_t(NO_ERROR);
163256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    }
163356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
16346c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    int index_wake_up_event = findWakeUpSensorEventLocked(scratch, count);
16356c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    if (index_wake_up_event >= 0) {
16366c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        scratch[index_wake_up_event].flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
16376c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        ++mWakeLockRefCount;
1638e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#if DEBUG_CONNECTIONS
1639e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella        ++mTotalAcksNeeded;
1640e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#endif
16416c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    }
164256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
164356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    // NOTE: ASensorEvent and sensors_event_t are the same type.
164456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    ssize_t size = SensorEventQueue::write(mChannel,
164556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                                    reinterpret_cast<ASensorEvent const*>(scratch), count);
164656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    if (size < 0) {
164756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        // Write error, copy events to local cache.
16486c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        if (index_wake_up_event >= 0) {
16496c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            // If there was a wake_up sensor_event, reset the flag.
16506c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            scratch[index_wake_up_event].flags &= ~WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
16510ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella            if (mWakeLockRefCount > 0) {
16520ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella                --mWakeLockRefCount;
16530ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella            }
1654e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#if DEBUG_CONNECTIONS
1655e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella            --mTotalAcksNeeded;
1656e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#endif
16576c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        }
165856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        if (mEventCache == NULL) {
165956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            mMaxCacheSize = computeMaxCacheSizeLocked();
166056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            mEventCache = new sensors_event_t[mMaxCacheSize];
166156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            mCacheSize = 0;
166256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        }
166356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        memcpy(&mEventCache[mCacheSize], scratch, count * sizeof(sensors_event_t));
166456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        mCacheSize += count;
166556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
166656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        // Add this file descriptor to the looper to get a callback when this fd is available for
166756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        // writing.
16688a96955c8e14db40b16164236830fc9506a00872Aravind Akella        updateLooperRegistrationLocked(mService->getLooper());
166956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        return size;
167056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    }
167156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
167256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#if DEBUG_CONNECTIONS
167356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    if (size > 0) {
167456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        mEventsSent += count;
167556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    }
167656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#endif
167756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
167856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    return size < 0 ? status_t(size) : status_t(NO_ERROR);
167956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella}
168056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
16816c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akellavoid SensorService::SensorEventConnection::reAllocateCacheLocked(sensors_event_t const* scratch,
16826c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                                                                 int count) {
16836c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    sensors_event_t *eventCache_new;
16846c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    const int new_cache_size = computeMaxCacheSizeLocked();
16856c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    // Allocate new cache, copy over events from the old cache & scratch, free up memory.
16866c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    eventCache_new = new sensors_event_t[new_cache_size];
16876c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    memcpy(eventCache_new, mEventCache, mCacheSize * sizeof(sensors_event_t));
16886c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    memcpy(&eventCache_new[mCacheSize], scratch, count * sizeof(sensors_event_t));
16896c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
16906c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    ALOGD_IF(DEBUG_CONNECTIONS, "reAllocateCacheLocked maxCacheSize=%d %d", mMaxCacheSize,
16916c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            new_cache_size);
16926c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
16936c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    delete mEventCache;
16946c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    mEventCache = eventCache_new;
16956c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    mCacheSize += count;
16966c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    mMaxCacheSize = new_cache_size;
16976c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella}
16986c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
16996c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akellavoid SensorService::SensorEventConnection::sendPendingFlushEventsLocked() {
17006c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    ASensorEvent flushCompleteEvent;
17010ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella    memset(&flushCompleteEvent, 0, sizeof(flushCompleteEvent));
17026c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    flushCompleteEvent.type = SENSOR_TYPE_META_DATA;
17036c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    // Loop through all the sensors for this connection and check if there are any pending
17046c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    // flush complete events to be sent.
17056c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
17066c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        FlushInfo& flushInfo = mSensorInfo.editValueAt(i);
17076c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        while (flushInfo.mPendingFlushEventsToSend > 0) {
17080ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella            const int sensor_handle = mSensorInfo.keyAt(i);
17090ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella            flushCompleteEvent.meta_data.sensor = sensor_handle;
1710b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            bool wakeUpSensor = mService->getSensorFromHandle(sensor_handle).isWakeUpSensor();
1711b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            if (wakeUpSensor) {
1712b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella               ++mWakeLockRefCount;
17130ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella               flushCompleteEvent.flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
17140ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella            }
17156c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            ssize_t size = SensorEventQueue::write(mChannel, &flushCompleteEvent, 1);
17166c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            if (size < 0) {
1717b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella                if (wakeUpSensor) --mWakeLockRefCount;
17186c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                return;
17194c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
17206c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            ALOGD_IF(DEBUG_CONNECTIONS, "sent dropped flush complete event==%d ",
17216c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                    flushCompleteEvent.meta_data.sensor);
17226c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            flushInfo.mPendingFlushEventsToSend--;
17234c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
17244c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
17256c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella}
17266c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
1727b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::SensorEventConnection::writeToSocketFromCache() {
17285466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella    // At a time write at most half the size of the receiver buffer in SensorEventQueue OR
17295466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella    // half the size of the socket buffer allocated in BitTube whichever is smaller.
17305466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella    const int maxWriteSize = helpers::min(SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT/2,
17315466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            int(mService->mSocketBufferSize/(sizeof(sensors_event_t)*2)));
1732b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    Mutex::Autolock _l(mConnectionLock);
17335466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella    // Send pending flush complete events (if any)
17346c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    sendPendingFlushEventsLocked();
173556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    for (int numEventsSent = 0; numEventsSent < mCacheSize;) {
17365466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella        const int numEventsToWrite = helpers::min(mCacheSize - numEventsSent, maxWriteSize);
17376c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        int index_wake_up_event =
17386c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                  findWakeUpSensorEventLocked(mEventCache + numEventsSent, numEventsToWrite);
17396c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        if (index_wake_up_event >= 0) {
17406c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            mEventCache[index_wake_up_event + numEventsSent].flags |=
17416c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                    WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
17426c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            ++mWakeLockRefCount;
1743e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#if DEBUG_CONNECTIONS
1744e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella            ++mTotalAcksNeeded;
1745e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#endif
17466c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        }
174756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
174856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        ssize_t size = SensorEventQueue::write(mChannel,
174956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                          reinterpret_cast<ASensorEvent const*>(mEventCache + numEventsSent),
17506c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                          numEventsToWrite);
175156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        if (size < 0) {
17526c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            if (index_wake_up_event >= 0) {
17536c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                // If there was a wake_up sensor_event, reset the flag.
17546c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                mEventCache[index_wake_up_event + numEventsSent].flags  &=
17556c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                        ~WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
17560ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella                if (mWakeLockRefCount > 0) {
17570ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella                    --mWakeLockRefCount;
17580ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella                }
1759e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#if DEBUG_CONNECTIONS
1760e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella                --mTotalAcksNeeded;
1761e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#endif
17626c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            }
176356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            memmove(mEventCache, &mEventCache[numEventsSent],
176456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                                 (mCacheSize - numEventsSent) * sizeof(sensors_event_t));
176556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            ALOGD_IF(DEBUG_CONNECTIONS, "wrote %d events from cache size==%d ",
17666c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                    numEventsSent, mCacheSize);
176756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            mCacheSize -= numEventsSent;
176856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            return;
176956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        }
17706c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        numEventsSent += numEventsToWrite;
177156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#if DEBUG_CONNECTIONS
17726c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        mEventsSentFromCache += numEventsToWrite;
177356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella#endif
1774fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
177556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    ALOGD_IF(DEBUG_CONNECTIONS, "wrote all events from cache size=%d ", mCacheSize);
177656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    // All events from the cache have been sent. Reset cache size to zero.
177756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    mCacheSize = 0;
17788a96955c8e14db40b16164236830fc9506a00872Aravind Akella    // There are no more events in the cache. We don't need to poll for write on the fd.
17798a96955c8e14db40b16164236830fc9506a00872Aravind Akella    // Update Looper registration.
17808a96955c8e14db40b16164236830fc9506a00872Aravind Akella    updateLooperRegistrationLocked(mService->getLooper());
1781fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1782fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1783c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akellavoid SensorService::SensorEventConnection::countFlushCompleteEventsLocked(
17840ec2066e4774b851c66176b99b0a5aa5abe6ad00Aravind Akella                sensors_event_t const* scratch, const int numEventsDropped) {
17854c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    ALOGD_IF(DEBUG_CONNECTIONS, "dropping %d events ", numEventsDropped);
17864c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    // Count flushComplete events in the events that are about to the dropped. These will be sent
17874c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    // separately before the next batch of events.
17884c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    for (int j = 0; j < numEventsDropped; ++j) {
17894c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        if (scratch[j].type == SENSOR_TYPE_META_DATA) {
17904c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            FlushInfo& flushInfo = mSensorInfo.editValueFor(scratch[j].meta_data.sensor);
17914c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            flushInfo.mPendingFlushEventsToSend++;
17924c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            ALOGD_IF(DEBUG_CONNECTIONS, "increment pendingFlushCount %d",
17934c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                     flushInfo.mPendingFlushEventsToSend);
17944c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
17954c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
17964c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    return;
17974c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella}
17984c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
17996c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akellaint SensorService::SensorEventConnection::findWakeUpSensorEventLocked(
18006c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                       sensors_event_t const* scratch, const int count) {
18019a844cf78f09953145200b4074d47589257a408cAravind Akella    for (int i = 0; i < count; ++i) {
18029a844cf78f09953145200b4074d47589257a408cAravind Akella        if (mService->isWakeUpSensorEvent(scratch[i])) {
18036c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            return i;
18049a844cf78f09953145200b4074d47589257a408cAravind Akella        }
18059a844cf78f09953145200b4074d47589257a408cAravind Akella    }
18066c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    return -1;
18079a844cf78f09953145200b4074d47589257a408cAravind Akella}
18089a844cf78f09953145200b4074d47589257a408cAravind Akella
1809b3989276d17f2b083bec67b695d1078fb86c6c53Mathias Agopiansp<BitTube> SensorService::SensorEventConnection::getSensorChannel() const
1810fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
1811fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return mChannel;
1812fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1813fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1814fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::SensorEventConnection::enableDisable(
1815724d91d778e71c8186399f4955de14b54812b3edAravind Akella        int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
1816724d91d778e71c8186399f4955de14b54812b3edAravind Akella        int reservedFlags)
1817fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
1818fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    status_t err;
1819fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (enabled) {
1820724d91d778e71c8186399f4955de14b54812b3edAravind Akella        err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
1821b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                               reservedFlags, mOpPackageName);
182256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
1823fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    } else {
1824fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        err = mService->disable(this, handle);
1825fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
1826fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return err;
1827fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1828fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1829fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::SensorEventConnection::setEventRate(
1830724d91d778e71c8186399f4955de14b54812b3edAravind Akella        int handle, nsecs_t samplingPeriodNs)
1831fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
1832b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    return mService->setEventRate(this, handle, samplingPeriodNs, mOpPackageName);
1833fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1834fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1835701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akellastatus_t  SensorService::SensorEventConnection::flush() {
1836b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    return  mService->flushSensor(this, mOpPackageName);
1837724d91d778e71c8186399f4955de14b54812b3edAravind Akella}
18384c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
18398a96955c8e14db40b16164236830fc9506a00872Aravind Akellaint SensorService::SensorEventConnection::handleEvent(int fd, int events, void* /*data*/) {
184056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    if (events & ALOOPER_EVENT_HANGUP || events & ALOOPER_EVENT_ERROR) {
18418a96955c8e14db40b16164236830fc9506a00872Aravind Akella        {
18428a96955c8e14db40b16164236830fc9506a00872Aravind Akella            // If the Looper encounters some error, set the flag mDead, reset mWakeLockRefCount,
18438a96955c8e14db40b16164236830fc9506a00872Aravind Akella            // and remove the fd from Looper. Call checkWakeLockState to know if SensorService
18448a96955c8e14db40b16164236830fc9506a00872Aravind Akella            // can release the wake-lock.
18458a96955c8e14db40b16164236830fc9506a00872Aravind Akella            ALOGD_IF(DEBUG_CONNECTIONS, "%p Looper error %d", this, fd);
18468a96955c8e14db40b16164236830fc9506a00872Aravind Akella            Mutex::Autolock _l(mConnectionLock);
18478a96955c8e14db40b16164236830fc9506a00872Aravind Akella            mDead = true;
18488a96955c8e14db40b16164236830fc9506a00872Aravind Akella            mWakeLockRefCount = 0;
18498a96955c8e14db40b16164236830fc9506a00872Aravind Akella            updateLooperRegistrationLocked(mService->getLooper());
18508a96955c8e14db40b16164236830fc9506a00872Aravind Akella        }
18518a96955c8e14db40b16164236830fc9506a00872Aravind Akella        mService->checkWakeLockState();
1852a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        if (mDataInjectionMode) {
1853a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella            // If the Looper has encountered some error in data injection mode, reset SensorService
1854a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella            // back to normal mode.
1855a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella            mService->resetToNormalMode();
1856a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella            mDataInjectionMode = false;
1857a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        }
18588a96955c8e14db40b16164236830fc9506a00872Aravind Akella        return 1;
18599a844cf78f09953145200b4074d47589257a408cAravind Akella    }
186056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
186156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    if (events & ALOOPER_EVENT_INPUT) {
1862a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        unsigned char buf[sizeof(sensors_event_t)];
1863a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        ssize_t numBytesRead = ::recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
186456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        {
186556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella           Mutex::Autolock _l(mConnectionLock);
1866a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella           if (numBytesRead == sizeof(sensors_event_t)) {
1867a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               if (!mDataInjectionMode) {
1868a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella                   ALOGE("Data injected in normal mode, dropping event"
1869a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella                         "package=%s uid=%d", mPackageName.string(), mUid);
1870a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella                   // Unregister call backs.
1871a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella                   return 0;
1872a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               }
1873a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               SensorDevice& dev(SensorDevice::getInstance());
1874a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               sensors_event_t sensor_event;
1875a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               memset(&sensor_event, 0, sizeof(sensor_event));
1876a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               memcpy(&sensor_event, buf, sizeof(sensors_event_t));
1877a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               Sensor sensor = mService->getSensorFromHandle(sensor_event.sensor);
1878a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               sensor_event.type = sensor.getType();
1879b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav               dev.injectSensorData(&sensor_event);
1880e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#if DEBUG_CONNECTIONS
1881a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               ++mEventsReceived;
1882e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella#endif
1883a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella           } else if (numBytesRead == sizeof(uint32_t)) {
1884a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               uint32_t numAcks = 0;
188508f04bf36c3f5d2e91de5525dfce778e56464fc2Aravind Akella               memcpy(&numAcks, buf, numBytesRead);
1886a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               // Sanity check to ensure  there are no read errors in recv, numAcks is always
1887a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               // within the range and not zero. If any of the above don't hold reset
1888a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               // mWakeLockRefCount to zero.
1889a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               if (numAcks > 0 && numAcks < mWakeLockRefCount) {
1890a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella                   mWakeLockRefCount -= numAcks;
1891a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               } else {
1892a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella                   mWakeLockRefCount = 0;
1893a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               }
1894a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella#if DEBUG_CONNECTIONS
1895a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               mTotalAcksReceived += numAcks;
1896a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella#endif
1897a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella           } else {
1898a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               // Read error, reset wakelock refcount.
1899a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               mWakeLockRefCount = 0;
1900a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella           }
190156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        }
190256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        // Check if wakelock can be released by sensorservice. mConnectionLock needs to be released
190356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        // here as checkWakeLockState() will need it.
190456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        if (mWakeLockRefCount == 0) {
190556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            mService->checkWakeLockState();
190656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        }
190756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        // continue getting callbacks.
190856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        return 1;
190956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    }
191056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
191156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    if (events & ALOOPER_EVENT_OUTPUT) {
1912b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        // send sensor data that is stored in mEventCache for this connection.
1913b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        mService->sendEventsFromCache(this);
19149a844cf78f09953145200b4074d47589257a408cAravind Akella    }
191556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    return 1;
191656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella}
191756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
191856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellaint SensorService::SensorEventConnection::computeMaxCacheSizeLocked() const {
1919b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    size_t fifoWakeUpSensors = 0;
1920b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    size_t fifoNonWakeUpSensors = 0;
192156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
192256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        const Sensor& sensor = mService->getSensorFromHandle(mSensorInfo.keyAt(i));
192356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        if (sensor.getFifoReservedEventCount() == sensor.getFifoMaxEventCount()) {
192456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            // Each sensor has a reserved fifo. Sum up the fifo sizes for all wake up sensors and
192556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            // non wake_up sensors.
192656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            if (sensor.isWakeUpSensor()) {
192756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                fifoWakeUpSensors += sensor.getFifoReservedEventCount();
192856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            } else {
192956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                fifoNonWakeUpSensors += sensor.getFifoReservedEventCount();
193056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            }
193156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        } else {
193256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            // Shared fifo. Compute the max of the fifo sizes for wake_up and non_wake up sensors.
193356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            if (sensor.isWakeUpSensor()) {
193456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                fifoWakeUpSensors = fifoWakeUpSensors > sensor.getFifoMaxEventCount() ?
193556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                                          fifoWakeUpSensors : sensor.getFifoMaxEventCount();
193656ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
193756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            } else {
193856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                fifoNonWakeUpSensors = fifoNonWakeUpSensors > sensor.getFifoMaxEventCount() ?
193956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella                                          fifoNonWakeUpSensors : sensor.getFifoMaxEventCount();
194056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
194156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            }
194256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        }
194356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella   }
194456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella   if (fifoWakeUpSensors + fifoNonWakeUpSensors == 0) {
194556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella       // It is extremely unlikely that there is a write failure in non batch mode. Return a cache
19466c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella       // size that is equal to that of the batch mode.
1947e74baf6ca7d57375f38540b6b7ac5e4af019951bAravind Akella       // ALOGW("Write failure in non-batch mode");
19486c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella       return MAX_SOCKET_BUFFER_SIZE_BATCHED/sizeof(sensors_event_t);
194956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella   }
195056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella   return fifoWakeUpSensors + fifoNonWakeUpSensors;
19519a844cf78f09953145200b4074d47589257a408cAravind Akella}
19529a844cf78f09953145200b4074d47589257a408cAravind Akella
1953fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// ---------------------------------------------------------------------------
1954fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}; // namespace android
1955fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1956