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
17fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <stdint.h>
18f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include <math.h>
19fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <sys/types.h>
20fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
213301542828febc768e1df42892cfac4992c35474Mathias Agopian#include <cutils/properties.h>
223301542828febc768e1df42892cfac4992c35474Mathias Agopian
23fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <utils/SortedVector.h>
24fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <utils/KeyedVector.h>
25fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <utils/threads.h>
26fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <utils/Atomic.h>
27fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <utils/Errors.h>
28fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <utils/RefBase.h>
29451beee076cac09f817abae78a990dea108a9482Mathias Agopian#include <utils/Singleton.h>
30c4a930d1d5a432a1f302763ac55460d6e83fe7e0Mathias Agopian#include <utils/String16.h>
31fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
32fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <binder/BinderService.h>
33451beee076cac09f817abae78a990dea108a9482Mathias Agopian#include <binder/IServiceManager.h>
341cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian#include <binder/PermissionCache.h>
35fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
36fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <gui/ISensorServer.h>
37fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <gui/ISensorEventConnection.h>
38907103bf186cfdd2ed9eb3b6c36de53ade7b16f6Mathias Agopian#include <gui/SensorEventQueue.h>
39fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
40fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <hardware/sensors.h>
414342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh#include <hardware_legacy/power.h>
42fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
43787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian#include "BatteryService.h"
44984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "CorrectedGyroSensor.h"
45f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "GravitySensor.h"
46f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "LinearAccelerationSensor.h"
47984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "OrientationSensor.h"
48f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "RotationVectorSensor.h"
49984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "SensorFusion.h"
50984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "SensorService.h"
51fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
52fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopiannamespace android {
53fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// ---------------------------------------------------------------------------
54fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
553301542828febc768e1df42892cfac4992c35474Mathias Agopian/*
563301542828febc768e1df42892cfac4992c35474Mathias Agopian * Notes:
573301542828febc768e1df42892cfac4992c35474Mathias Agopian *
583301542828febc768e1df42892cfac4992c35474Mathias Agopian * - what about a gyro-corrected magnetic-field sensor?
593301542828febc768e1df42892cfac4992c35474Mathias Agopian * - run mag sensor from time to time to force calibration
603301542828febc768e1df42892cfac4992c35474Mathias Agopian * - gravity sensor length is wrong (=> drift in linear-acc sensor)
613301542828febc768e1df42892cfac4992c35474Mathias Agopian *
623301542828febc768e1df42892cfac4992c35474Mathias Agopian */
633301542828febc768e1df42892cfac4992c35474Mathias Agopian
644342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganeshconst char* SensorService::WAKE_LOCK_NAME = "SensorService";
654342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
66fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorService()
671cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian    : mInitCheck(NO_INIT)
68fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
69fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
70fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
71fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianvoid SensorService::onFirstRef()
72fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
73a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block    ALOGD("nuSensorService starting...");
7450df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
75f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    SensorDevice& dev(SensorDevice::getInstance());
76fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
77f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    if (dev.initCheck() == NO_ERROR) {
78f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        sensor_t const* list;
797b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian        ssize_t count = dev.getSensorList(&list);
807b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian        if (count > 0) {
817b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            ssize_t orientationIndex = -1;
827b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            bool hasGyro = false;
837b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            uint32_t virtualSensorsNeeds =
847b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    (1<<SENSOR_TYPE_GRAVITY) |
857b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    (1<<SENSOR_TYPE_LINEAR_ACCELERATION) |
867b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    (1<<SENSOR_TYPE_ROTATION_VECTOR);
877b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian
887b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            mLastEventSeen.setCapacity(count);
897b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            for (ssize_t i=0 ; i<count ; i++) {
907b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                registerSensor( new HardwareSensor(list[i]) );
917b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                switch (list[i].type) {
927b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_ORIENTATION:
937b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        orientationIndex = i;
947b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        break;
957b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_GYROSCOPE:
960319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
977b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        hasGyro = true;
987b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        break;
997b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_GRAVITY:
1007b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_LINEAR_ACCELERATION:
1017b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_ROTATION_VECTOR:
1027b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        virtualSensorsNeeds &= ~(1<<list[i].type);
1037b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        break;
1047b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                }
10550df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian            }
106fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1077b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            // it's safe to instantiate the SensorFusion object here
1087b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            // (it wants to be instantiated after h/w sensors have been
1097b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            // registered)
1107b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            const SensorFusion& fusion(SensorFusion::getInstance());
1117b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian
1120319306670b0344da99efa606b6f172dde575a39Mathias Agopian            // build the sensor list returned to users
1130319306670b0344da99efa606b6f172dde575a39Mathias Agopian            mUserSensorList = mSensorList;
1140319306670b0344da99efa606b6f172dde575a39Mathias Agopian
1157b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            if (hasGyro) {
1160319306670b0344da99efa606b6f172dde575a39Mathias Agopian                Sensor aSensor;
1177b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian
1180319306670b0344da99efa606b6f172dde575a39Mathias Agopian                // Add Android virtual sensors if they're not already
1190319306670b0344da99efa606b6f172dde575a39Mathias Agopian                // available in the HAL
1207b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian
1210319306670b0344da99efa606b6f172dde575a39Mathias Agopian                aSensor = registerVirtualSensor( new RotationVectorSensor() );
1220319306670b0344da99efa606b6f172dde575a39Mathias Agopian                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
1230319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    mUserSensorList.add(aSensor);
1240319306670b0344da99efa606b6f172dde575a39Mathias Agopian                }
125f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
1260319306670b0344da99efa606b6f172dde575a39Mathias Agopian                aSensor = registerVirtualSensor( new GravitySensor(list, count) );
1270319306670b0344da99efa606b6f172dde575a39Mathias Agopian                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) {
1280319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    mUserSensorList.add(aSensor);
1290319306670b0344da99efa606b6f172dde575a39Mathias Agopian                }
13033264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian
1310319306670b0344da99efa606b6f172dde575a39Mathias Agopian                aSensor = registerVirtualSensor( new LinearAccelerationSensor(list, count) );
1320319306670b0344da99efa606b6f172dde575a39Mathias Agopian                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) {
1330319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    mUserSensorList.add(aSensor);
1340319306670b0344da99efa606b6f172dde575a39Mathias Agopian                }
13533264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian
1360319306670b0344da99efa606b6f172dde575a39Mathias Agopian                aSensor = registerVirtualSensor( new OrientationSensor() );
1370319306670b0344da99efa606b6f172dde575a39Mathias Agopian                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
1380319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    // if we are doing our own rotation-vector, also add
1390319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    // the orientation sensor and remove the HAL provided one.
1400319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    mUserSensorList.replaceAt(aSensor, orientationIndex);
1417b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                }
1420319306670b0344da99efa606b6f172dde575a39Mathias Agopian
1430319306670b0344da99efa606b6f172dde575a39Mathias Agopian                // virtual debugging sensors are not added to mUserSensorList
1440319306670b0344da99efa606b6f172dde575a39Mathias Agopian                registerVirtualSensor( new CorrectedGyroSensor(list, count) );
1450319306670b0344da99efa606b6f172dde575a39Mathias Agopian                registerVirtualSensor( new GyroDriftSensor() );
146010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian            }
147010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian
14833264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian            // debugging sensor list
1490319306670b0344da99efa606b6f172dde575a39Mathias Agopian            mUserSensorListDebug = mSensorList;
15033264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian
1514c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            mSocketBufferSize = SOCKET_BUFFER_SIZE_NON_BATCHED;
1524c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            FILE *fp = fopen("/proc/sys/net/core/wmem_max", "r");
1534c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            char line[128];
1544c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            if (fp != NULL && fgets(line, sizeof(line), fp) != NULL) {
1554c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                line[sizeof(line) - 1] = '\0';
1564c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                sscanf(line, "%u", &mSocketBufferSize);
1574c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                if (mSocketBufferSize > MAX_SOCKET_BUFFER_SIZE_BATCHED) {
1584c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                    mSocketBufferSize = MAX_SOCKET_BUFFER_SIZE_BATCHED;
1594c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                }
1604c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
1614c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            ALOGD("Max socket buffer size %u", mSocketBufferSize);
1624c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            if (fp) {
1634c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                fclose(fp);
1644c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
1654c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
1667b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            run("SensorService", PRIORITY_URGENT_DISPLAY);
1677b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            mInitCheck = NO_ERROR;
1687b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian        }
169fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
170fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
171fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1720319306670b0344da99efa606b6f172dde575a39Mathias AgopianSensor SensorService::registerSensor(SensorInterface* s)
173f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{
174f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    sensors_event_t event;
175f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    memset(&event, 0, sizeof(event));
176f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
177f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    const Sensor sensor(s->getSensor());
178f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    // add to the sensor list (returned to clients)
179f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    mSensorList.add(sensor);
180f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    // add to our handle->SensorInterface mapping
181f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    mSensorMap.add(sensor.getHandle(), s);
182f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    // create an entry in the mLastEventSeen array
183f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    mLastEventSeen.add(sensor.getHandle(), event);
1840319306670b0344da99efa606b6f172dde575a39Mathias Agopian
1850319306670b0344da99efa606b6f172dde575a39Mathias Agopian    return sensor;
186f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
187f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
1880319306670b0344da99efa606b6f172dde575a39Mathias AgopianSensor SensorService::registerVirtualSensor(SensorInterface* s)
189f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{
1900319306670b0344da99efa606b6f172dde575a39Mathias Agopian    Sensor sensor = registerSensor(s);
191f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    mVirtualSensorList.add( s );
1920319306670b0344da99efa606b6f172dde575a39Mathias Agopian    return sensor;
193f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
194f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
195fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::~SensorService()
196fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
197f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    for (size_t i=0 ; i<mSensorMap.size() ; i++)
198f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        delete mSensorMap.valueAt(i);
199fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
200fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
2011cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopianstatic const String16 sDump("android.permission.DUMP");
2021cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian
203fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::dump(int fd, const Vector<String16>& args)
204fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
205fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    String8 result;
2061cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian    if (!PermissionCache::checkCallingPermission(sDump)) {
207ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian        result.appendFormat("Permission Denial: "
208fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
209fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian                IPCThreadState::self()->getCallingPid(),
210fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian                IPCThreadState::self()->getCallingUid());
211fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    } else {
212fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        Mutex::Autolock _l(mLock);
213ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian        result.append("Sensor List:\n");
2143560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        for (size_t i=0 ; i<mSensorList.size() ; i++) {
2153560fb24b668675627934356f210d84d19bf4e56Mathias Agopian            const Sensor& s(mSensorList[i]);
2163560fb24b668675627934356f210d84d19bf4e56Mathias Agopian            const sensors_event_t& e(mLastEventSeen.valueFor(s.getHandle()));
217ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            result.appendFormat(
218ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    "%-48s| %-32s | 0x%08x | ",
2193560fb24b668675627934356f210d84d19bf4e56Mathias Agopian                    s.getName().string(),
2203560fb24b668675627934356f210d84d19bf4e56Mathias Agopian                    s.getVendor().string(),
221ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    s.getHandle());
222ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian
223ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            if (s.getMinDelay() > 0) {
224ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                result.appendFormat(
225ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    "maxRate=%7.2fHz | ", 1e6f / s.getMinDelay());
226ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            } else {
227ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                result.append(s.getMinDelay() == 0
228ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                        ? "on-demand         | "
229ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                        : "one-shot          | ");
230ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            }
231724d91d778e71c8186399f4955de14b54812b3edAravind Akella            if (s.getFifoMaxEventCount() > 0) {
232724d91d778e71c8186399f4955de14b54812b3edAravind Akella                result.appendFormat("getFifoMaxEventCount=%d events | ", s.getFifoMaxEventCount());
233724d91d778e71c8186399f4955de14b54812b3edAravind Akella            } else {
234724d91d778e71c8186399f4955de14b54812b3edAravind Akella                result.append("no batching support | ");
235724d91d778e71c8186399f4955de14b54812b3edAravind Akella            }
236ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian
237ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            switch (s.getType()) {
238ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_ROTATION_VECTOR:
239ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
240ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    result.appendFormat(
241ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                            "last=<%5.1f,%5.1f,%5.1f,%5.1f,%5.1f>\n",
242ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                            e.data[0], e.data[1], e.data[2], e.data[3], e.data[4]);
243ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    break;
244ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
245ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
246ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    result.appendFormat(
247ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                            "last=<%5.1f,%5.1f,%5.1f,%5.1f,%5.1f,%5.1f>\n",
248ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                            e.data[0], e.data[1], e.data[2], e.data[3], e.data[4], e.data[5]);
249ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    break;
250ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_GAME_ROTATION_VECTOR:
251ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    result.appendFormat(
252ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                            "last=<%5.1f,%5.1f,%5.1f,%5.1f>\n",
253ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                            e.data[0], e.data[1], e.data[2], e.data[3]);
254ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    break;
255ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_SIGNIFICANT_MOTION:
256ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_STEP_DETECTOR:
257ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    result.appendFormat( "last=<%f>\n", e.data[0]);
258ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    break;
259ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                case SENSOR_TYPE_STEP_COUNTER:
260ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    result.appendFormat( "last=<%llu>\n", e.u64.step_counter);
261ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    break;
262ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                default:
263ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    // default to 3 values
264ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    result.appendFormat(
265ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                            "last=<%5.1f,%5.1f,%5.1f>\n",
266ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                            e.data[0], e.data[1], e.data[2]);
267ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian                    break;
268ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            }
2693560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        }
270ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian        SensorFusion::getInstance().dump(result);
271ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian        SensorDevice::getInstance().dump(result);
272ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian
273ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian        result.append("Active sensors:\n");
274fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        for (size_t i=0 ; i<mActiveSensors.size() ; i++) {
2755d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian            int handle = mActiveSensors.keyAt(i);
276ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            result.appendFormat("%s (handle=0x%08x, connections=%d)\n",
2775d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian                    getSensorName(handle).string(),
2785d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian                    handle,
279fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian                    mActiveSensors.valueAt(i)->getNumConnections());
280fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
2814c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
2824c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        result.appendFormat("%u Max Socket Buffer size\n", mSocketBufferSize);
2834c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        result.appendFormat("%d active connections\n", mActiveConnections.size());
2844c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
2854c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        for (size_t i=0 ; i < mActiveConnections.size() ; i++) {
2864c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            sp<SensorEventConnection> connection(mActiveConnections[i].promote());
2874c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            if (connection != 0) {
2884c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                result.appendFormat("Connection Number: %d \n", i);
2894c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                connection->dump(result);
2904c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
2914c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
292fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
293fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    write(fd, result.string(), result.size());
294fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return NO_ERROR;
295fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
296fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
2974342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganeshvoid SensorService::cleanupAutoDisabledSensor(const sp<SensorEventConnection>& connection,
2984342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        sensors_event_t const* buffer, const int count) {
2994c01b1ad80e084f0cd1057f89fdd1fcedf19dd96Jaikumar Ganesh    SensorInterface* sensor;
3004c01b1ad80e084f0cd1057f89fdd1fcedf19dd96Jaikumar Ganesh    status_t err = NO_ERROR;
3014342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    for (int i=0 ; i<count ; i++) {
3024342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        int handle = buffer[i].sensor;
3037438fd1a0132bc6de101e2a5f75040a119b6f29bMathias Agopian        int type = buffer[i].type;
3047438fd1a0132bc6de101e2a5f75040a119b6f29bMathias Agopian        if (type == SENSOR_TYPE_SIGNIFICANT_MOTION) {
3054342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            if (connection->hasSensor(handle)) {
3064c01b1ad80e084f0cd1057f89fdd1fcedf19dd96Jaikumar Ganesh                sensor = mSensorMap.valueFor(handle);
307ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian                if (sensor != NULL) {
308ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian                    sensor->autoDisable(connection.get(), handle);
3094c01b1ad80e084f0cd1057f89fdd1fcedf19dd96Jaikumar Ganesh                }
3104342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                cleanupWithoutDisable(connection, handle);
3114342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            }
3124342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
3134342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
3144342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh}
3154342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
316fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::threadLoop()
317fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
318a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block    ALOGD("nuSensorService thread starting...");
319fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
32090ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    // each virtual sensor could generate an event per "real" event, that's why we need
32190ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    // to size numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT.
32290ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    // in practice, this is too aggressive, but guaranteed to be enough.
32390ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
32490ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    const size_t numEventMax = minBufferSize / (1 + mVirtualSensorList.size());
32590ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian
326d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian    sensors_event_t buffer[minBufferSize];
327d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian    sensors_event_t scratch[minBufferSize];
328f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    SensorDevice& device(SensorDevice::getInstance());
329f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    const size_t vcount = mVirtualSensorList.size();
330fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
331f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    ssize_t count;
3324342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    bool wakeLockAcquired = false;
3334342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    const int halVersion = device.getHalDeviceVersion();
334fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    do {
335f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        count = device.poll(buffer, numEventMax);
336fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        if (count<0) {
337f5a1230d322c14c42331d0a1536b50c87742973bSteve Block            ALOGE("sensor poll failed (%s)", strerror(-count));
338fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            break;
339fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
340fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
3414342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // Poll has returned. Hold a wakelock.
3424342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // Todo(): add a flag to the sensors definitions to indicate
3434342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // the sensors which can wake up the AP
3444342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        for (int i = 0; i < count; i++) {
3457438fd1a0132bc6de101e2a5f75040a119b6f29bMathias Agopian            if (buffer[i].type == SENSOR_TYPE_SIGNIFICANT_MOTION) {
3464342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
3474342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                 wakeLockAcquired = true;
3484342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                 break;
3494342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            }
3504342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
3514342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
35294e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian        recordLastValue(buffer, count);
35394e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian
354f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        // handle virtual sensors
355f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        if (count && vcount) {
356984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian            sensors_event_t const * const event = buffer;
357f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            const DefaultKeyedVector<int, SensorInterface*> virtualSensors(
358f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    getActiveVirtualSensors());
359f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            const size_t activeVirtualSensorCount = virtualSensors.size();
360f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            if (activeVirtualSensorCount) {
361f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                size_t k = 0;
362984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                SensorFusion& fusion(SensorFusion::getInstance());
363984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                if (fusion.isEnabled()) {
364984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                    for (size_t i=0 ; i<size_t(count) ; i++) {
365984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                        fusion.process(event[i]);
366984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                    }
367984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                }
368d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) {
369f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {
370d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                        if (count + k >= minBufferSize) {
371d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                            ALOGE("buffer too small to hold all events: "
372d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                                    "count=%u, k=%u, size=%u",
373d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                                    count, k, minBufferSize);
374d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                            break;
375d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                        }
376f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                        sensors_event_t out;
377d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                        SensorInterface* si = virtualSensors.valueAt(j);
378d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                        if (si->process(&out, event[i])) {
379f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                            buffer[count + k] = out;
380f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                            k++;
381f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                        }
382f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    }
383f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                }
384f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                if (k) {
385f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    // record the last synthesized values
386f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    recordLastValue(&buffer[count], k);
387f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    count += k;
388f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    // sort the buffer by time-stamps
389f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    sortEventBuffer(buffer, count);
390f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                }
391f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            }
392f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        }
393f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
3944342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // handle backward compatibility for RotationVector sensor
3954342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) {
3964342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            for (int i = 0; i < count; i++) {
3977438fd1a0132bc6de101e2a5f75040a119b6f29bMathias Agopian                if (buffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) {
3984342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                    // All the 4 components of the quaternion should be available
3994342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                    // No heading accuracy. Set it to -1
4004342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                    buffer[i].data[4] = -1;
4014342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                }
4024342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            }
4034342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
4044342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
405f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        // send our events to clients...
406fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        const SortedVector< wp<SensorEventConnection> > activeConnections(
407fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian                getActiveConnections());
408fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        size_t numConnections = activeConnections.size();
409f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        for (size_t i=0 ; i<numConnections ; i++) {
410f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            sp<SensorEventConnection> connection(
411f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    activeConnections[i].promote());
412f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            if (connection != 0) {
413f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                connection->sendEvents(buffer, count, scratch);
4144342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                // Some sensors need to be auto disabled after the trigger
4154342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                cleanupAutoDisabledSensor(connection, buffer, count);
416fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            }
417fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
4184342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
4194342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // We have read the data, upper layers should hold the wakelock.
4204342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (wakeLockAcquired) release_wake_lock(WAKE_LOCK_NAME);
421fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    } while (count >= 0 || Thread::exitPending());
422fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
4233c20fbed7f3a916ced10f2ed5a272271b7d81edeSteve Block    ALOGW("Exiting SensorService::threadLoop => aborting...");
4241a62301fc58cd2af18239b0415813461bf5fc41bMathias Agopian    abort();
425fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return false;
426fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
427fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
42894e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopianvoid SensorService::recordLastValue(
4294b84704b97300eff3ebfab85652e64d54149d205Aravind Akella        const sensors_event_t* buffer, size_t count) {
43094e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian    Mutex::Autolock _l(mLock);
4314b84704b97300eff3ebfab85652e64d54149d205Aravind Akella    const sensors_event_t* last = NULL;
4324b84704b97300eff3ebfab85652e64d54149d205Aravind Akella    for (size_t i = 0; i < count; i++) {
4334b84704b97300eff3ebfab85652e64d54149d205Aravind Akella        const sensors_event_t* event = &buffer[i];
4344b84704b97300eff3ebfab85652e64d54149d205Aravind Akella        if (event->type != SENSOR_TYPE_META_DATA) {
4354b84704b97300eff3ebfab85652e64d54149d205Aravind Akella            if (last && event->sensor != last->sensor) {
4364b84704b97300eff3ebfab85652e64d54149d205Aravind Akella                mLastEventSeen.editValueFor(last->sensor) = *last;
4374b84704b97300eff3ebfab85652e64d54149d205Aravind Akella            }
4384b84704b97300eff3ebfab85652e64d54149d205Aravind Akella            last = event;
43994e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian        }
44094e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian    }
4414b84704b97300eff3ebfab85652e64d54149d205Aravind Akella    if (last) {
4424b84704b97300eff3ebfab85652e64d54149d205Aravind Akella        mLastEventSeen.editValueFor(last->sensor) = *last;
4434b84704b97300eff3ebfab85652e64d54149d205Aravind Akella    }
44494e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian}
44594e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian
446f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopianvoid SensorService::sortEventBuffer(sensors_event_t* buffer, size_t count)
447f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{
448f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    struct compar {
449f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        static int cmp(void const* lhs, void const* rhs) {
450f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            sensors_event_t const* l = static_cast<sensors_event_t const*>(lhs);
451f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            sensors_event_t const* r = static_cast<sensors_event_t const*>(rhs);
452a5c106a4f0afcf061728a1cb7c8c3b908728575dMathias Agopian            return l->timestamp - r->timestamp;
453f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        }
454f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    };
455f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    qsort(buffer, count, sizeof(sensors_event_t), compar::cmp);
456f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
457f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
458fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSortedVector< wp<SensorService::SensorEventConnection> >
459fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::getActiveConnections() const
460fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
461fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    Mutex::Autolock _l(mLock);
462fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return mActiveConnections;
463fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
464fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
465f001c92436b4a66eb7687286325ced7f10c9f917Mathias AgopianDefaultKeyedVector<int, SensorInterface*>
466f001c92436b4a66eb7687286325ced7f10c9f917Mathias AgopianSensorService::getActiveVirtualSensors() const
467f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{
468f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    Mutex::Autolock _l(mLock);
469f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    return mActiveVirtualSensors;
470f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
471f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
4725d2707214dfb97bd8dfcc6620be36841d3c82420Mathias AgopianString8 SensorService::getSensorName(int handle) const {
473010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian    size_t count = mUserSensorList.size();
4745d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
475010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian        const Sensor& sensor(mUserSensorList[i]);
4765d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian        if (sensor.getHandle() == handle) {
4775d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian            return sensor.getName();
4785d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian        }
4795d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian    }
4805d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian    String8 result("unknown");
4815d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian    return result;
4825d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian}
4835d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian
484b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akellabool SensorService::isVirtualSensor(int handle) const {
485b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella    SensorInterface* sensor = mSensorMap.valueFor(handle);
486b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella    return sensor->isVirtual();
487b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella}
488b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella
489fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianVector<Sensor> SensorService::getSensorList()
490fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
49133264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian    char value[PROPERTY_VALUE_MAX];
49233264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian    property_get("debug.sensors", value, "0");
49333264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian    if (atoi(value)) {
49433264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian        return mUserSensorListDebug;
49533264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian    }
496010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian    return mUserSensorList;
497fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
498fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
499fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopiansp<ISensorEventConnection> SensorService::createSensorEventConnection()
500fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
5015307d17fe33fc26eeeacd6339a9fbfe96cf56873Mathias Agopian    uid_t uid = IPCThreadState::self()->getCallingUid();
5025307d17fe33fc26eeeacd6339a9fbfe96cf56873Mathias Agopian    sp<SensorEventConnection> result(new SensorEventConnection(this, uid));
503fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return result;
504fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
505fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
506db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopianvoid SensorService::cleanupConnection(SensorEventConnection* c)
507fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
508fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    Mutex::Autolock _l(mLock);
509db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian    const wp<SensorEventConnection> connection(c);
5107c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    size_t size = mActiveSensors.size();
511a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block    ALOGD_IF(DEBUG_CONNECTIONS, "%d active sensors", size);
5127c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    for (size_t i=0 ; i<size ; ) {
513db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        int handle = mActiveSensors.keyAt(i);
514db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        if (c->hasSensor(handle)) {
515a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block            ALOGD_IF(DEBUG_CONNECTIONS, "%i: disabling handle=0x%08x", i, handle);
516f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            SensorInterface* sensor = mSensorMap.valueFor( handle );
517f5a1230d322c14c42331d0a1536b50c87742973bSteve Block            ALOGE_IF(!sensor, "mSensorMap[handle=0x%08x] is null!", handle);
518f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            if (sensor) {
519db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian                sensor->activate(c, false);
520f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            }
521db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        }
522db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        SensorRecord* rec = mActiveSensors.valueAt(i);
523f5a1230d322c14c42331d0a1536b50c87742973bSteve Block        ALOGE_IF(!rec, "mActiveSensors[%d] is null (handle=0x%08x)!", i, handle);
524a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block        ALOGD_IF(DEBUG_CONNECTIONS,
525a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian                "removing connection %p for sensor[%d].handle=0x%08x",
526a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian                c, i, handle);
527a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian
528db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        if (rec && rec->removeConnection(connection)) {
529a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block            ALOGD_IF(DEBUG_CONNECTIONS, "... and it was the last connection");
5307c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            mActiveSensors.removeItemsAt(i, 1);
531f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            mActiveVirtualSensors.removeItem(handle);
5327c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            delete rec;
5337c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            size--;
5347c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian        } else {
5357c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            i++;
536fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
537fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
5387c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    mActiveConnections.remove(connection);
539787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian    BatteryService::cleanup(c->getUid());
540fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
541fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
542fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::enable(const sp<SensorEventConnection>& connection,
543724d91d778e71c8186399f4955de14b54812b3edAravind Akella        int handle, nsecs_t samplingPeriodNs,  nsecs_t maxBatchReportLatencyNs, int reservedFlags)
544fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
54550df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian    if (mInitCheck != NO_ERROR)
54650df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian        return mInitCheck;
54750df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
548f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    SensorInterface* sensor = mSensorMap.valueFor(handle);
549ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    if (sensor == NULL) {
550ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        return BAD_VALUE;
551ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    }
552ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    Mutex::Autolock _l(mLock);
5534342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    SensorRecord* rec = mActiveSensors.valueFor(handle);
5544342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (rec == 0) {
5554342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        rec = new SensorRecord(connection);
5564342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        mActiveSensors.add(handle, rec);
5574342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (sensor->isVirtual()) {
5584342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            mActiveVirtualSensors.add(handle, sensor);
5593560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        }
5604342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    } else {
5614342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (rec->addConnection(connection)) {
5624342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            // this sensor is already activated, but we are adding a
5634342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            // connection that uses it. Immediately send down the last
5644342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            // known value of the requested sensor if it's not a
5654342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            // "continuous" sensor.
5664342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            if (sensor->getSensor().getMinDelay() == 0) {
5674342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                sensors_event_t scratch;
5684342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                sensors_event_t& event(mLastEventSeen.editValueFor(handle));
5694342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                if (event.version == sizeof(sensors_event_t)) {
5704342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                    connection->sendEvents(&event, 1);
571f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                }
5727c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            }
573fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
574fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
5754342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
5764342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (connection->addSensor(handle)) {
5774342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        BatteryService::enableSensor(connection->getUid(), handle);
5784342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // the sensor was added (which means it wasn't already there)
5794342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // so, see if this connection becomes active
5804342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (mActiveConnections.indexOf(connection) < 0) {
5814342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            mActiveConnections.add(connection);
5824342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
5834342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    } else {
5844342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        ALOGW("sensor %08x already enabled in connection %p (ignoring)",
5854342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            handle, connection.get());
5864342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
5874342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
588724d91d778e71c8186399f4955de14b54812b3edAravind Akella    nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
589724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (samplingPeriodNs < minDelayNs) {
590724d91d778e71c8186399f4955de14b54812b3edAravind Akella        samplingPeriodNs = minDelayNs;
591724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
592724d91d778e71c8186399f4955de14b54812b3edAravind Akella
593724d91d778e71c8186399f4955de14b54812b3edAravind Akella    ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d rate=%lld timeout== %lld",
594724d91d778e71c8186399f4955de14b54812b3edAravind Akella             handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs);
595724d91d778e71c8186399f4955de14b54812b3edAravind Akella
596724d91d778e71c8186399f4955de14b54812b3edAravind Akella    status_t err = sensor->batch(connection.get(), handle, reservedFlags, samplingPeriodNs,
597724d91d778e71c8186399f4955de14b54812b3edAravind Akella                                 maxBatchReportLatencyNs);
5984c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    if (err == NO_ERROR) {
5994c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        connection->setFirstFlushPending(handle, true);
6004c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        status_t err_flush = sensor->flush(connection.get(), handle);
6014c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        // Flush may return error if the sensor is not activated or the underlying h/w sensor does
6024c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        // not support flush.
6034c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        if (err_flush != NO_ERROR) {
6044c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            connection->setFirstFlushPending(handle, false);
6054c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
6064c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
607724d91d778e71c8186399f4955de14b54812b3edAravind Akella
608724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (err == NO_ERROR) {
609724d91d778e71c8186399f4955de14b54812b3edAravind Akella        ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle);
610724d91d778e71c8186399f4955de14b54812b3edAravind Akella        err = sensor->activate(connection.get(), true);
611724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
612724d91d778e71c8186399f4955de14b54812b3edAravind Akella
6134342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (err != NO_ERROR) {
614724d91d778e71c8186399f4955de14b54812b3edAravind Akella        // batch/activate has failed, reset our state.
615ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        cleanupWithoutDisableLocked(connection, handle);
6164342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
617fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return err;
618fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
619fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
620fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::disable(const sp<SensorEventConnection>& connection,
621fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        int handle)
622fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
62350df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian    if (mInitCheck != NO_ERROR)
62450df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian        return mInitCheck;
62550df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
626ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    Mutex::Autolock _l(mLock);
627ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    status_t err = cleanupWithoutDisableLocked(connection, handle);
6284342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (err == NO_ERROR) {
6294342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        SensorInterface* sensor = mSensorMap.valueFor(handle);
6304342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        err = sensor ? sensor->activate(connection.get(), false) : status_t(BAD_VALUE);
6314342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
6324342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    return err;
6334342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh}
6344342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
635ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisable(
636ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        const sp<SensorEventConnection>& connection, int handle) {
637fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    Mutex::Autolock _l(mLock);
638ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    return cleanupWithoutDisableLocked(connection, handle);
639ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian}
640ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian
641ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisableLocked(
642ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        const sp<SensorEventConnection>& connection, int handle) {
643fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    SensorRecord* rec = mActiveSensors.valueFor(handle);
644fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (rec) {
645fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        // see if this connection becomes inactive
646787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian        if (connection->removeSensor(handle)) {
647787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian            BatteryService::disableSensor(connection->getUid(), handle);
648787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian        }
649fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        if (connection->hasAnySensor() == false) {
650fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            mActiveConnections.remove(connection);
651fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
652fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        // see if this sensor becomes inactive
653fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        if (rec->removeConnection(connection)) {
654fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            mActiveSensors.removeItem(handle);
655f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            mActiveVirtualSensors.removeItem(handle);
656fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            delete rec;
657fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
6584342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        return NO_ERROR;
6597c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    }
6604342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    return BAD_VALUE;
661fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
662fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
6637c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianstatus_t SensorService::setEventRate(const sp<SensorEventConnection>& connection,
664fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        int handle, nsecs_t ns)
665fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
66650df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian    if (mInitCheck != NO_ERROR)
66750df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian        return mInitCheck;
66850df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
669ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian    SensorInterface* sensor = mSensorMap.valueFor(handle);
670ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian    if (!sensor)
671ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian        return BAD_VALUE;
672ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian
6731cd700015318727d6d42236ab6274f1949fb08baMathias Agopian    if (ns < 0)
6741cd700015318727d6d42236ab6274f1949fb08baMathias Agopian        return BAD_VALUE;
6751cd700015318727d6d42236ab6274f1949fb08baMathias Agopian
67662569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian    nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
67762569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian    if (ns < minDelayNs) {
67862569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian        ns = minDelayNs;
679ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian    }
680ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian
681f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    return sensor->setDelay(connection.get(), handle, ns);
682fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
683fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
684724d91d778e71c8186399f4955de14b54812b3edAravind Akellastatus_t SensorService::flushSensor(const sp<SensorEventConnection>& connection,
685724d91d778e71c8186399f4955de14b54812b3edAravind Akella                                    int handle) {
686724d91d778e71c8186399f4955de14b54812b3edAravind Akella  if (mInitCheck != NO_ERROR) return mInitCheck;
687724d91d778e71c8186399f4955de14b54812b3edAravind Akella  SensorInterface* sensor = mSensorMap.valueFor(handle);
688701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella  if (sensor == NULL) {
689701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella      return BAD_VALUE;
690701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella  }
691701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella  if (sensor->getSensor().getType() == SENSOR_TYPE_SIGNIFICANT_MOTION) {
692701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella      ALOGE("flush called on Significant Motion sensor");
693701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella      return INVALID_OPERATION;
694724d91d778e71c8186399f4955de14b54812b3edAravind Akella  }
695724d91d778e71c8186399f4955de14b54812b3edAravind Akella  return sensor->flush(connection.get(), handle);
696724d91d778e71c8186399f4955de14b54812b3edAravind Akella}
697fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// ---------------------------------------------------------------------------
698fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
699fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorRecord::SensorRecord(
700fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        const sp<SensorEventConnection>& connection)
701fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
702fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    mConnections.add(connection);
703fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
704fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
7057c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianbool SensorService::SensorRecord::addConnection(
706fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        const sp<SensorEventConnection>& connection)
707fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
708fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (mConnections.indexOf(connection) < 0) {
709fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        mConnections.add(connection);
7107c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian        return true;
711fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
7127c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    return false;
713fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
714fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
715fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::SensorRecord::removeConnection(
716fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        const wp<SensorEventConnection>& connection)
717fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
718fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    ssize_t index = mConnections.indexOf(connection);
719fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (index >= 0) {
720fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        mConnections.removeItemsAt(index, 1);
721fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
722fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return mConnections.size() ? false : true;
723fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
724fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
725fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// ---------------------------------------------------------------------------
726fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
727fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorEventConnection::SensorEventConnection(
7285307d17fe33fc26eeeacd6339a9fbfe96cf56873Mathias Agopian        const sp<SensorService>& service, uid_t uid)
7294c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    : mService(service), mUid(uid)
730fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
7314c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    const SensorDevice& device(SensorDevice::getInstance());
7324c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    if (device.getHalDeviceVersion() >= SENSORS_DEVICE_API_VERSION_1_1) {
7334c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        // Increase socket buffer size to 1MB for batching capabilities.
7344c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        mChannel = new BitTube(service->mSocketBufferSize);
7354c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    } else {
7364c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        mChannel = new BitTube(SOCKET_BUFFER_SIZE_NON_BATCHED);
7374c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
738fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
739fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
740fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorEventConnection::~SensorEventConnection()
741fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
742a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block    ALOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this);
743fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    mService->cleanupConnection(this);
744fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
745fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
746fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianvoid SensorService::SensorEventConnection::onFirstRef()
747fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
748fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
749fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
7504c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akellavoid SensorService::SensorEventConnection::dump(String8& result) {
7514c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    Mutex::Autolock _l(mConnectionLock);
7524c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
7534c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        const FlushInfo& flushInfo = mSensorInfo.valueAt(i);
7544c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        result.appendFormat("\t %s | status: %s | pending flush events %d\n",
7554c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                            mService->getSensorName(mSensorInfo.keyAt(i)).string(),
7564c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                            flushInfo.mFirstFlushPending ? "First flush pending" :
7574c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                                                           "active",
7584c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                            flushInfo.mPendingFlushEventsToSend);
7594c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
7604c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella}
7614c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
7627c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianbool SensorService::SensorEventConnection::addSensor(int32_t handle) {
76371d7a5c289c6ef6b5fc86dd4784a075ca6470e38Mathias Agopian    Mutex::Autolock _l(mConnectionLock);
7644c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    if (mSensorInfo.indexOfKey(handle) < 0) {
7654c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        mSensorInfo.add(handle, FlushInfo());
7667c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian        return true;
767fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
7687c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    return false;
769fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
770fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
7717c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianbool SensorService::SensorEventConnection::removeSensor(int32_t handle) {
77271d7a5c289c6ef6b5fc86dd4784a075ca6470e38Mathias Agopian    Mutex::Autolock _l(mConnectionLock);
7734c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    if (mSensorInfo.removeItem(handle) >= 0) {
7747c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian        return true;
7757c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    }
7767c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    return false;
777fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
778fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
779fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
78071d7a5c289c6ef6b5fc86dd4784a075ca6470e38Mathias Agopian    Mutex::Autolock _l(mConnectionLock);
7814c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    return mSensorInfo.indexOfKey(handle) >= 0;
782fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
783fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
784fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianbool SensorService::SensorEventConnection::hasAnySensor() const {
78571d7a5c289c6ef6b5fc86dd4784a075ca6470e38Mathias Agopian    Mutex::Autolock _l(mConnectionLock);
7867c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    return mSensorInfo.size() ? true : false;
7877c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian}
7887c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian
7894c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akellavoid SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle,
7904c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                                bool value) {
7914c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    Mutex::Autolock _l(mConnectionLock);
7924c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    ssize_t index = mSensorInfo.indexOfKey(handle);
7934c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    if (index >= 0) {
7944c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
7954c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        flushInfo.mFirstFlushPending = value;
7964c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
7974c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella}
7984c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
799fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::SensorEventConnection::sendEvents(
800cf51001dbf28e9885fcacd4048902f1c75768fe9Mathias Agopian        sensors_event_t const* buffer, size_t numEvents,
801cf51001dbf28e9885fcacd4048902f1c75768fe9Mathias Agopian        sensors_event_t* scratch)
802fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
803cf51001dbf28e9885fcacd4048902f1c75768fe9Mathias Agopian    // filter out events not for this connection
8043560fb24b668675627934356f210d84d19bf4e56Mathias Agopian    size_t count = 0;
8054c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
8063560fb24b668675627934356f210d84d19bf4e56Mathias Agopian    if (scratch) {
80771d7a5c289c6ef6b5fc86dd4784a075ca6470e38Mathias Agopian        Mutex::Autolock _l(mConnectionLock);
8083560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        size_t i=0;
8093560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        while (i<numEvents) {
810724d91d778e71c8186399f4955de14b54812b3edAravind Akella            int32_t curr = buffer[i].sensor;
811724d91d778e71c8186399f4955de14b54812b3edAravind Akella            if (buffer[i].type == SENSOR_TYPE_META_DATA) {
812724d91d778e71c8186399f4955de14b54812b3edAravind Akella                ALOGD_IF(DEBUG_CONNECTIONS, "flush complete event sensor==%d ",
813724d91d778e71c8186399f4955de14b54812b3edAravind Akella                         buffer[i].meta_data.sensor);
814724d91d778e71c8186399f4955de14b54812b3edAravind Akella                // Setting curr to the correct sensor to ensure the sensor events per connection are
815724d91d778e71c8186399f4955de14b54812b3edAravind Akella                // filtered correctly. buffer[i].sensor is zero for meta_data events.
816724d91d778e71c8186399f4955de14b54812b3edAravind Akella                curr = buffer[i].meta_data.sensor;
817724d91d778e71c8186399f4955de14b54812b3edAravind Akella            }
8184c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            ssize_t index = mSensorInfo.indexOfKey(curr);
8194c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            if (index >= 0 && mSensorInfo[index].mFirstFlushPending == true &&
8204c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                buffer[i].type == SENSOR_TYPE_META_DATA) {
8214c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                // This is the first flush before activate is called. Events can now be sent for
8224c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                // this sensor on this connection.
8234c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                ALOGD_IF(DEBUG_CONNECTIONS, "First flush event for sensor==%d ",
8244c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                         buffer[i].meta_data.sensor);
8254c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                mSensorInfo.editValueAt(index).mFirstFlushPending = false;
8264c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
8274c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            if (index >= 0 && mSensorInfo[index].mFirstFlushPending == false)  {
8283560fb24b668675627934356f210d84d19bf4e56Mathias Agopian                do {
8294c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                    scratch[count++] = buffer[i++];
830724d91d778e71c8186399f4955de14b54812b3edAravind Akella                } while ((i<numEvents) && ((buffer[i].sensor == curr) ||
831724d91d778e71c8186399f4955de14b54812b3edAravind Akella                         (buffer[i].type == SENSOR_TYPE_META_DATA  &&
832724d91d778e71c8186399f4955de14b54812b3edAravind Akella                          buffer[i].meta_data.sensor == curr)));
8333560fb24b668675627934356f210d84d19bf4e56Mathias Agopian            } else {
8343560fb24b668675627934356f210d84d19bf4e56Mathias Agopian                i++;
8353560fb24b668675627934356f210d84d19bf4e56Mathias Agopian            }
836cf51001dbf28e9885fcacd4048902f1c75768fe9Mathias Agopian        }
8373560fb24b668675627934356f210d84d19bf4e56Mathias Agopian    } else {
8383560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        scratch = const_cast<sensors_event_t *>(buffer);
8393560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        count = numEvents;
840cf51001dbf28e9885fcacd4048902f1c75768fe9Mathias Agopian    }
841fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
8424c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    // Send pending flush events (if any) before sending events from the cache.
8434c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    {
8444c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        ASensorEvent flushCompleteEvent;
8454c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        flushCompleteEvent.type = SENSOR_TYPE_META_DATA;
8464c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        flushCompleteEvent.sensor = 0;
8474c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        Mutex::Autolock _l(mConnectionLock);
8484c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        // Loop through all the sensors for this connection and check if there are any pending
8494c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        // flush complete events to be sent.
8504c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        for (size_t i = 0; i < mSensorInfo.size(); ++i) {
8514c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            FlushInfo& flushInfo = mSensorInfo.editValueAt(i);
8524c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            while (flushInfo.mPendingFlushEventsToSend > 0) {
8534c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                flushCompleteEvent.meta_data.sensor = mSensorInfo.keyAt(i);
8544c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                ssize_t size = SensorEventQueue::write(mChannel, &flushCompleteEvent, 1);
8554c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                if (size < 0) {
8564c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                    // ALOGW("dropping %d events on the floor", count);
857c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella                    countFlushCompleteEventsLocked(scratch, count);
8584c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                    return size;
8594c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                }
8604c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                ALOGD_IF(DEBUG_CONNECTIONS, "sent dropped flush complete event==%d ",
8614c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                         flushCompleteEvent.meta_data.sensor);
8624c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                flushInfo.mPendingFlushEventsToSend--;
8634c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
8644c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
8654c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
8664c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
867b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella    // Early return if there are no events for this connection.
868b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella    if (count == 0) {
869b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella        return status_t(NO_ERROR);
870b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella    }
871b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella
872907103bf186cfdd2ed9eb3b6c36de53ade7b16f6Mathias Agopian    // NOTE: ASensorEvent and sensors_event_t are the same type
873907103bf186cfdd2ed9eb3b6c36de53ade7b16f6Mathias Agopian    ssize_t size = SensorEventQueue::write(mChannel,
874907103bf186cfdd2ed9eb3b6c36de53ade7b16f6Mathias Agopian            reinterpret_cast<ASensorEvent const*>(scratch), count);
875fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (size == -EAGAIN) {
876fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        // the destination doesn't accept events anymore, it's probably
877fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        // full. For now, we just drop the events on the floor.
8784c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        // ALOGW("dropping %d events on the floor", count);
879c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella        Mutex::Autolock _l(mConnectionLock);
880c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella        countFlushCompleteEventsLocked(scratch, count);
881fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        return size;
882fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
883fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
8841e0b1e8491e5f6dc59faabe70cbfa942853150e0Jeff Brown    return size < 0 ? status_t(size) : status_t(NO_ERROR);
885fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
886fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
887c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akellavoid SensorService::SensorEventConnection::countFlushCompleteEventsLocked(
8884c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                sensors_event_t* scratch, const int numEventsDropped) {
8894c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    ALOGD_IF(DEBUG_CONNECTIONS, "dropping %d events ", numEventsDropped);
8904c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    // Count flushComplete events in the events that are about to the dropped. These will be sent
8914c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    // separately before the next batch of events.
8924c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    for (int j = 0; j < numEventsDropped; ++j) {
8934c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        if (scratch[j].type == SENSOR_TYPE_META_DATA) {
8944c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            FlushInfo& flushInfo = mSensorInfo.editValueFor(scratch[j].meta_data.sensor);
8954c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            flushInfo.mPendingFlushEventsToSend++;
8964c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            ALOGD_IF(DEBUG_CONNECTIONS, "increment pendingFlushCount %d",
8974c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                     flushInfo.mPendingFlushEventsToSend);
8984c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
8994c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
9004c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    return;
9014c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella}
9024c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
903b3989276d17f2b083bec67b695d1078fb86c6c53Mathias Agopiansp<BitTube> SensorService::SensorEventConnection::getSensorChannel() const
904fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
905fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return mChannel;
906fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
907fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
908fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::SensorEventConnection::enableDisable(
909724d91d778e71c8186399f4955de14b54812b3edAravind Akella        int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
910724d91d778e71c8186399f4955de14b54812b3edAravind Akella        int reservedFlags)
911fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
912fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    status_t err;
913fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (enabled) {
914724d91d778e71c8186399f4955de14b54812b3edAravind Akella        err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
915724d91d778e71c8186399f4955de14b54812b3edAravind Akella                               reservedFlags);
916fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    } else {
917fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        err = mService->disable(this, handle);
918fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
919fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return err;
920fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
921fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
922fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::SensorEventConnection::setEventRate(
923724d91d778e71c8186399f4955de14b54812b3edAravind Akella        int handle, nsecs_t samplingPeriodNs)
924fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian{
925724d91d778e71c8186399f4955de14b54812b3edAravind Akella    return mService->setEventRate(this, handle, samplingPeriodNs);
926fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
927fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
928701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akellastatus_t  SensorService::SensorEventConnection::flush() {
929c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella    SensorDevice& dev(SensorDevice::getInstance());
930c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella    const int halVersion = dev.getHalDeviceVersion();
931701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella    Mutex::Autolock _l(mConnectionLock);
932701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella    status_t err(NO_ERROR);
933c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella    // Loop through all sensors for this connection and call flush on each of them.
934701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
935701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella        const int handle = mSensorInfo.keyAt(i);
936b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella        if (halVersion < SENSORS_DEVICE_API_VERSION_1_1 || mService->isVirtualSensor(handle)) {
937c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella            // For older devices just increment pending flush count which will send a trivial
938c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella            // flush complete event.
939c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella            FlushInfo& flushInfo = mSensorInfo.editValueFor(handle);
940c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella            flushInfo.mPendingFlushEventsToSend++;
941c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella        } else {
942c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella            status_t err_flush = mService->flushSensor(this, handle);
943c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella            if (err_flush != NO_ERROR) {
944c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella                ALOGE("Flush error handle=%d %s", handle, strerror(-err_flush));
945c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella            }
946c551eac5b16a53f872cbb692d3a0c81e39329725Aravind Akella            err = (err_flush != NO_ERROR) ? err_flush : err;
947701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella        }
948701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella    }
949701166d9f60a6e1149ff568aec0e03f3f3925292Aravind Akella    return err;
950724d91d778e71c8186399f4955de14b54812b3edAravind Akella}
9514c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
952fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// ---------------------------------------------------------------------------
953fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}; // namespace android
954fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
955