1fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian/*
2fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * Copyright (C) 2010 The Android Open Source Project
3fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian *
4fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License");
5fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * you may not use this file except in compliance with the License.
6fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * You may obtain a copy of the License at
7fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian *
8fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian *      http://www.apache.org/licenses/LICENSE-2.0
9fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian *
10fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * Unless required by applicable law or agreed to in writing, software
11fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS,
12fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * See the License for the specific language governing permissions and
14fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian * limitations under the License.
15fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian */
16b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav#include <binder/AppOpsManager.h>
17fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <binder/BinderService.h>
18451beee076cac09f817abae78a990dea108a9482Mathias Agopian#include <binder/IServiceManager.h>
191cb13461a8cf62e3ba634e5965332f2d284f6d42Mathias Agopian#include <binder/PermissionCache.h>
20e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu#include <cutils/ashmem.h>
21dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu#include <cutils/properties.h>
22fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian#include <hardware/sensors.h>
234342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh#include <hardware_legacy/power.h>
248b1517ced6a294f479e261961d03c7356dec0838Brian Duddie#include <log/log.h>
2553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <openssl/digest.h>
2653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <openssl/hmac.h>
2753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <openssl/rand.h>
28dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu#include <sensor/SensorEventQueue.h>
29dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu#include <utils/SystemClock.h>
3053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser
31787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian#include "BatteryService.h"
32984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "CorrectedGyroSensor.h"
33f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "GravitySensor.h"
34f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "LinearAccelerationSensor.h"
35984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "OrientationSensor.h"
36f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "RotationVectorSensor.h"
37984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "SensorFusion.h"
38755c451c7861a029e26e5f16e319b629169e656dPeng Xu#include "SensorInterface.h"
39eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu
40984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "SensorService.h"
41e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu#include "SensorDirectConnection.h"
42eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include "SensorEventAckReceiver.h"
436a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu#include "SensorEventConnection.h"
44eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include "SensorRecord.h"
45eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include "SensorRegistrationInfo.h"
46eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu
47eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <inttypes.h>
48eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <math.h>
4998d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu#include <sched.h>
50eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <stdint.h>
51eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu#include <sys/socket.h>
5253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <sys/stat.h>
5353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <sys/types.h>
5453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#include <unistd.h>
55fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
56fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopiannamespace android {
57fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian// ---------------------------------------------------------------------------
58fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
593301542828febc768e1df42892cfac4992c35474Mathias Agopian/*
603301542828febc768e1df42892cfac4992c35474Mathias Agopian * Notes:
613301542828febc768e1df42892cfac4992c35474Mathias Agopian *
623301542828febc768e1df42892cfac4992c35474Mathias Agopian * - what about a gyro-corrected magnetic-field sensor?
633301542828febc768e1df42892cfac4992c35474Mathias Agopian * - run mag sensor from time to time to force calibration
643301542828febc768e1df42892cfac4992c35474Mathias Agopian * - gravity sensor length is wrong (=> drift in linear-acc sensor)
653301542828febc768e1df42892cfac4992c35474Mathias Agopian *
663301542828febc768e1df42892cfac4992c35474Mathias Agopian */
673301542828febc768e1df42892cfac4992c35474Mathias Agopian
688ef3c89eb2030395f8a342bd16dbb344957ab275Aravind Akellaconst char* SensorService::WAKE_LOCK_NAME = "SensorService_wakelock";
6953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiseruint8_t SensorService::sHmacGlobalKey[128] = {};
7053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiserbool SensorService::sHmacGlobalKeyIsValid = false;
7153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser
7253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#define SENSOR_SERVICE_DIR "/data/system/sensor_service"
7353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser#define SENSOR_SERVICE_HMAC_KEY_FILE  SENSOR_SERVICE_DIR "/hmac_key"
7498d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu#define SENSOR_SERVICE_SCHED_FIFO_PRIORITY 10
7553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser
76a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella// Permissions.
77dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xustatic const String16 sDumpPermission("android.permission.DUMP");
78dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xustatic const String16 sLocationHardwarePermission("android.permission.LOCATION_HARDWARE");
794342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
80fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias AgopianSensorService::SensorService()
818a96955c8e14db40b16164236830fc9506a00872Aravind Akella    : mInitCheck(NO_INIT), mSocketBufferSize(SOCKET_BUFFER_SIZE_NON_BATCHED),
8247e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu      mWakeLockAcquired(false) {
83fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
84fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
8553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiserbool SensorService::initializeHmacKey() {
8653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    int fd = open(SENSOR_SERVICE_HMAC_KEY_FILE, O_RDONLY|O_CLOEXEC);
8753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    if (fd != -1) {
8853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        int result = read(fd, sHmacGlobalKey, sizeof(sHmacGlobalKey));
8953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        close(fd);
9053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        if (result == sizeof(sHmacGlobalKey)) {
9153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser            return true;
9253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        }
9353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        ALOGW("Unable to read HMAC key; generating new one.");
9453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    }
9553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser
9653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    if (RAND_bytes(sHmacGlobalKey, sizeof(sHmacGlobalKey)) == -1) {
9753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        ALOGW("Can't generate HMAC key; dynamic sensor getId() will be wrong.");
9853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        return false;
9953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    }
10053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser
10153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    // We need to make sure this is only readable to us.
10253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    bool wroteKey = false;
10353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    mkdir(SENSOR_SERVICE_DIR, S_IRWXU);
10453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    fd = open(SENSOR_SERVICE_HMAC_KEY_FILE, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC,
10553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser              S_IRUSR|S_IWUSR);
10653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    if (fd != -1) {
10753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        int result = write(fd, sHmacGlobalKey, sizeof(sHmacGlobalKey));
10853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        close(fd);
10953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        wroteKey = (result == sizeof(sHmacGlobalKey));
11053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    }
11153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    if (wroteKey) {
11253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        ALOGI("Generated new HMAC key.");
11353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    } else {
11453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        ALOGW("Unable to write HMAC key; dynamic sensor getId() will change "
11553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser              "after reboot.");
11653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    }
11753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    // Even if we failed to write the key we return true, because we did
11853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    // initialize the HMAC key.
11953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    return true;
12053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser}
12153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser
12298d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu// Set main thread to SCHED_FIFO to lower sensor event latency when system is under load
12398d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xuvoid SensorService::enableSchedFifoMode() {
12498d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu    struct sched_param param = {0};
12598d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu    param.sched_priority = SENSOR_SERVICE_SCHED_FIFO_PRIORITY;
12698d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu    if (sched_setscheduler(getTid(), SCHED_FIFO | SCHED_RESET_ON_FORK, &param) != 0) {
12798d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu        ALOGE("Couldn't set SCHED_FIFO for SensorService thread");
12898d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu    }
12998d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu}
13098d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu
13147e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xuvoid SensorService::onFirstRef() {
132a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block    ALOGD("nuSensorService starting...");
133f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    SensorDevice& dev(SensorDevice::getInstance());
134fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
13553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    sHmacGlobalKeyIsValid = initializeHmacKey();
13653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser
137f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    if (dev.initCheck() == NO_ERROR) {
138f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        sensor_t const* list;
1397b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian        ssize_t count = dev.getSensorList(&list);
1407b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian        if (count > 0) {
1417b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            ssize_t orientationIndex = -1;
142f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella            bool hasGyro = false, hasAccel = false, hasMag = false;
1437b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            uint32_t virtualSensorsNeeds =
1447b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    (1<<SENSOR_TYPE_GRAVITY) |
1457b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    (1<<SENSOR_TYPE_LINEAR_ACCELERATION) |
146f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                    (1<<SENSOR_TYPE_ROTATION_VECTOR) |
147f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                    (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR) |
148f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                    (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR);
1497b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian
1507b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            for (ssize_t i=0 ; i<count ; i++) {
151f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                bool useThisSensor=true;
152f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu
1537b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                switch (list[i].type) {
154f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella                    case SENSOR_TYPE_ACCELEROMETER:
155f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella                        hasAccel = true;
156f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella                        break;
157f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella                    case SENSOR_TYPE_MAGNETIC_FIELD:
158f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella                        hasMag = true;
159f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella                        break;
1607b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_ORIENTATION:
1617b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        orientationIndex = i;
1627b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        break;
1637b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_GYROSCOPE:
1640319306670b0344da99efa606b6f172dde575a39Mathias Agopian                    case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
1657b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        hasGyro = true;
1667b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        break;
1677b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_GRAVITY:
1687b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_LINEAR_ACCELERATION:
1697b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                    case SENSOR_TYPE_ROTATION_VECTOR:
170f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                    case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
171f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                    case SENSOR_TYPE_GAME_ROTATION_VECTOR:
172f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                        if (IGNORE_HARDWARE_FUSION) {
173f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                            useThisSensor = false;
174f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                        } else {
175f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                            virtualSensorsNeeds &= ~(1<<list[i].type);
176f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                        }
1777b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                        break;
1787b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian                }
179f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                if (useThisSensor) {
180f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                    registerSensor( new HardwareSensor(list[i]) );
181f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu                }
18250df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian            }
183fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1847b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            // it's safe to instantiate the SensorFusion object here
1857b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            // (it wants to be instantiated after h/w sensors have been
1867b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian            // registered)
187d4036b6b7f9609fe09efabdbfbb8c8f9428f76f7Andreas Gampe            SensorFusion::getInstance();
1887b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian
189f504789dd3b3073de176fd2fa09dd9fc9de5bc1fAravind Akella            if (hasGyro && hasAccel && hasMag) {
1900319306670b0344da99efa606b6f172dde575a39Mathias Agopian                // Add Android virtual sensors if they're not already
1910319306670b0344da99efa606b6f172dde575a39Mathias Agopian                // available in the HAL
1920cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                bool needRotationVector =
1930cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                        (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) != 0;
1947b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian
1950cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                registerSensor(new RotationVectorSensor(), !needRotationVector, true);
1960cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                registerSensor(new OrientationSensor(), !needRotationVector, true);
197f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
1980cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                bool needLinearAcceleration =
1990cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                        (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) != 0;
2000319306670b0344da99efa606b6f172dde575a39Mathias Agopian
2010cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                registerSensor(new LinearAccelerationSensor(list, count),
2020cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                               !needLinearAcceleration, true);
203f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu
2040cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                // virtual debugging sensors are not for user
205755c451c7861a029e26e5f16e319b629169e656dPeng Xu                registerSensor( new CorrectedGyroSensor(list, count), true, true);
206755c451c7861a029e26e5f16e319b629169e656dPeng Xu                registerSensor( new GyroDriftSensor(), true, true);
207010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian            }
208010e42230135815907e76e5d7e5f30edf9e1799dMathias Agopian
209f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu            if (hasAccel && hasGyro) {
2100cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                bool needGravitySensor = (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) != 0;
2110cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                registerSensor(new GravitySensor(list, count), !needGravitySensor, true);
212f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu
2130cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                bool needGameRotationVector =
2140cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                        (virtualSensorsNeeds & (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR)) != 0;
2150cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                registerSensor(new GameRotationVectorSensor(), !needGameRotationVector, true);
216f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu            }
217f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu
218f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu            if (hasAccel && hasMag) {
2190cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                bool needGeoMagRotationVector =
2200cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                        (virtualSensorsNeeds & (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR)) != 0;
2210cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                registerSensor(new GeoMagRotationVectorSensor(), !needGeoMagRotationVector, true);
222f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu            }
223f66684a6fb2a2991e84a085673629db2a0494fc6Peng Xu
2245466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            // Check if the device really supports batching by looking at the FIFO event
2255466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            // counts for each sensor.
2265466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            bool batchingSupported = false;
2270cc8f809924706c7d683da30605f432635dd5bb6Peng Xu            mSensors.forEachSensor(
2280cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                    [&batchingSupported] (const Sensor& s) -> bool {
2290cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                        if (s.getFifoMaxEventCount() > 0) {
2300cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                            batchingSupported = true;
2310cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                        }
2320cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                        return !batchingSupported;
2330cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                    });
2345466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella
2355466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            if (batchingSupported) {
2365466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                // Increase socket buffer size to a max of 100 KB for batching capabilities.
2375466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                mSocketBufferSize = MAX_SOCKET_BUFFER_SIZE_BATCHED;
2385466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            } else {
2395466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                mSocketBufferSize = SOCKET_BUFFER_SIZE_NON_BATCHED;
2405466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            }
2415466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella
2425466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            // Compare the socketBufferSize value against the system limits and limit
2435466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            // it to maxSystemSocketBufferSize if necessary.
2444c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            FILE *fp = fopen("/proc/sys/net/core/wmem_max", "r");
2454c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            char line[128];
2464c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            if (fp != NULL && fgets(line, sizeof(line), fp) != NULL) {
2474c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                line[sizeof(line) - 1] = '\0';
2485466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                size_t maxSystemSocketBufferSize;
2495466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                sscanf(line, "%zu", &maxSystemSocketBufferSize);
2505466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                if (mSocketBufferSize > maxSystemSocketBufferSize) {
2515466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella                    mSocketBufferSize = maxSystemSocketBufferSize;
2524c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                }
2534c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
2544c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            if (fp) {
2554c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella                fclose(fp);
2564c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
2574c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
2589a844cf78f09953145200b4074d47589257a408cAravind Akella            mWakeLockAcquired = false;
25956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella            mLooper = new Looper(false);
2608493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
2618493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            mSensorEventBuffer = new sensors_event_t[minBufferSize];
2628493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            mSensorEventScratch = new sensors_event_t[minBufferSize];
263eb05947ae2c4ac3a80712fed9382d82cb9aedad5Peng Xu            mMapFlushEventsToConnections = new wp<const SensorEventConnection> [minBufferSize];
264a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella            mCurrentOperatingMode = NORMAL;
2657830ef3dd0ff3749d974c2dd85a8fa59dc47aecaAravind Akella
26618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            mNextSensorRegIndex = 0;
26718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            for (int i = 0; i < SENSOR_REGISTRATIONS_BUF_SIZE; ++i) {
26818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                mLastNSensorRegistrations.push();
26918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            }
27018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella
27118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            mInitCheck = NO_ERROR;
272b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            mAckReceiver = new SensorEventAckReceiver(this);
273b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
2747830ef3dd0ff3749d974c2dd85a8fa59dc47aecaAravind Akella            run("SensorService", PRIORITY_URGENT_DISPLAY);
27598d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu
27698d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu            // priority can only be changed after run
27798d30f627ef96ca6e47c9cbcbdcfb63adbeda424Peng Xu            enableSchedFifoMode();
2787b2b32f2e761a919deb6f82d978b379429f77b05Mathias Agopian        }
279fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
280fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
281fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
2820cc8f809924706c7d683da30605f432635dd5bb6Peng Xuconst Sensor& SensorService::registerSensor(SensorInterface* s, bool isDebug, bool isVirtual) {
2830cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    int handle = s->getSensor().getHandle();
2846a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    int type = s->getSensor().getType();
2850cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    if (mSensors.add(handle, s, isDebug, isVirtual)){
2866a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu        mRecentEvent.emplace(handle, new RecentEventLogger(type));
2870cc8f809924706c7d683da30605f432635dd5bb6Peng Xu        return s->getSensor();
2880cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    } else {
2890cc8f809924706c7d683da30605f432635dd5bb6Peng Xu        return mSensors.getNonSensor();
2900cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    }
291f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
292f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
2936a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xuconst Sensor& SensorService::registerDynamicSensorLocked(SensorInterface* s, bool isDebug) {
2940cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    return registerSensor(s, isDebug);
2952576cb63b3fe1592f54816625036566b9eb0793aPeng Xu}
2962576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
2976a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xubool SensorService::unregisterDynamicSensorLocked(int handle) {
2980cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    bool ret = mSensors.remove(handle);
2996a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
3006a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    const auto i = mRecentEvent.find(handle);
3016a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    if (i != mRecentEvent.end()) {
3026a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu        delete i->second;
3036a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu        mRecentEvent.erase(i);
3042576cb63b3fe1592f54816625036566b9eb0793aPeng Xu    }
3050cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    return ret;
306f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
307f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
3080cc8f809924706c7d683da30605f432635dd5bb6Peng Xuconst Sensor& SensorService::registerVirtualSensor(SensorInterface* s, bool isDebug) {
3090cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    return registerSensor(s, isDebug, true);
31047e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu}
31147e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu
31247e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng XuSensorService::~SensorService() {
3136a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    for (auto && entry : mRecentEvent) {
3146a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu        delete entry.second;
3156a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    }
316fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
317fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
31847e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xustatus_t SensorService::dump(int fd, const Vector<String16>& args) {
319fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    String8 result;
320dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu    if (!PermissionCache::checkCallingPermission(sDumpPermission)) {
321eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu        result.appendFormat("Permission Denial: can't dump SensorService from pid=%d, uid=%d\n",
322fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian                IPCThreadState::self()->getCallingPid(),
323fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian                IPCThreadState::self()->getCallingUid());
324444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    } else {
325fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu        bool privileged = IPCThreadState::self()->getCallingUid() == 0;
326841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella        if (args.size() > 2) {
3274949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella           return INVALID_OPERATION;
3284949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        }
3294949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        Mutex::Autolock _l(mLock);
3304949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        SensorDevice& dev(SensorDevice::getInstance());
331841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella        if (args.size() == 2 && args[0] == String16("restrict")) {
332444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            // If already in restricted mode. Ignore.
333444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            if (mCurrentOperatingMode == RESTRICTED) {
334444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                return status_t(NO_ERROR);
335444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            }
336444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            // If in any mode other than normal, ignore.
337444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            if (mCurrentOperatingMode != NORMAL) {
338444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                return INVALID_OPERATION;
339444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            }
340e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu
341a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella            mCurrentOperatingMode = RESTRICTED;
342e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu            // temporarily stop all sensor direct report
343e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu            for (auto &i : mDirectConnections) {
344e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu                sp<SensorDirectConnection> connection(i.promote());
345e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu                if (connection != nullptr) {
346e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu                    connection->stopAll(true /* backupRecord */);
347e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu                }
348e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu            }
349e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu
3504949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            dev.disableAllSensors();
3514949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            // Clear all pending flush connections for all active sensors. If one of the active
3524949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            // connections has called flush() and the underlying sensor has been disabled before a
3534949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            // flush complete event is returned, we need to remove the connection from this queue.
3544949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            for (size_t i=0 ; i< mActiveSensors.size(); ++i) {
3554949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella                mActiveSensors.valueAt(i)->clearAllPendingFlushConnections();
3564949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            }
357841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            mWhiteListedPackage.setTo(String8(args[1]));
358444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            return status_t(NO_ERROR);
359444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        } else if (args.size() == 1 && args[0] == String16("enable")) {
360444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            // If currently in restricted mode, reset back to NORMAL mode else ignore.
361444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            if (mCurrentOperatingMode == RESTRICTED) {
362444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                mCurrentOperatingMode = NORMAL;
363444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                dev.enableAllSensors();
364e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu                // recover all sensor direct report
365e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu                for (auto &i : mDirectConnections) {
366e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu                    sp<SensorDirectConnection> connection(i.promote());
367e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu                    if (connection != nullptr) {
368e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu                        connection->recoverAll();
369e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu                    }
370e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu                }
3716c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            }
372841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            if (mCurrentOperatingMode == DATA_INJECTION) {
373841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella               resetToNormalModeLocked();
374841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            }
375841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            mWhiteListedPackage.clear();
376444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            return status_t(NO_ERROR);
377841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella        } else if (args.size() == 2 && args[0] == String16("data_injection")) {
378841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            if (mCurrentOperatingMode == NORMAL) {
379841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                dev.disableAllSensors();
380841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                status_t err = dev.setMode(DATA_INJECTION);
381841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                if (err == NO_ERROR) {
382841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                    mCurrentOperatingMode = DATA_INJECTION;
383841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                } else {
384841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                    // Re-enable sensors.
385841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                    dev.enableAllSensors();
386841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                }
387841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                mWhiteListedPackage.setTo(String8(args[1]));
388841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                return NO_ERROR;
389841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            } else if (mCurrentOperatingMode == DATA_INJECTION) {
390841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                // Already in DATA_INJECTION mode. Treat this as a no_op.
391841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                return NO_ERROR;
392841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            } else {
393841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                // Transition to data injection mode supported only from NORMAL mode.
394841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                return INVALID_OPERATION;
395841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella            }
3960cc8f809924706c7d683da30605f432635dd5bb6Peng Xu        } else if (!mSensors.hasAnySensor()) {
397ee155cadb23e84542cbf445c2aac89ae63df4cc7Aravind Akella            result.append("No Sensors on the device\n");
39853e5aa93fa2855616b9691c5e1878f1db1464aceAshutosh Joshi            result.appendFormat("devInitCheck : %d\n", SensorDevice::getInstance().initCheck());
399444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella        } else {
400444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            // Default dump the sensor list and debugging information.
4010cc8f809924706c7d683da30605f432635dd5bb6Peng Xu            //
4026a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu            result.append("Sensor Device:\n");
4036a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu            result.append(SensorDevice::getInstance().dump().c_str());
4046a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
4056a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu            result.append("Sensor List:\n");
4060cc8f809924706c7d683da30605f432635dd5bb6Peng Xu            result.append(mSensors.dump().c_str());
4076c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
4086a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu            result.append("Fusion States:\n");
409444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            SensorFusion::getInstance().dump(result);
410444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella
4110cc8f809924706c7d683da30605f432635dd5bb6Peng Xu            result.append("Recent Sensor events:\n");
4126a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu            for (auto&& i : mRecentEvent) {
4136a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                sp<SensorInterface> s = mSensors.getInterface(i.first);
414fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu                if (!i.second->isEmpty()) {
415fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu                    if (privileged || s->getSensor().getRequiredPermission().isEmpty()) {
416fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu                        i.second->setFormat("normal");
417fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu                    } else {
418fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu                        i.second->setFormat("mask_data");
419fba3c11b5ebf947827d7578373feef48ac12bd8cPeng Xu                    }
4206a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                    // if there is events and sensor does not need special permission.
4216a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                    result.appendFormat("%s: ", s->getSensor().getName().string());
4226a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                    result.append(i.second->dump().c_str());
4236a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                }
4246a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu            }
4250cc8f809924706c7d683da30605f432635dd5bb6Peng Xu
426444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            result.append("Active sensors:\n");
427444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            for (size_t i=0 ; i<mActiveSensors.size() ; i++) {
428444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                int handle = mActiveSensors.keyAt(i);
429444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                result.appendFormat("%s (handle=0x%08x, connections=%zu)\n",
430444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        getSensorName(handle).string(),
431444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        handle,
432444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        mActiveSensors.valueAt(i)->getNumConnections());
433ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian            }
4344c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
435d4036b6b7f9609fe09efabdbfbb8c8f9428f76f7Andreas Gampe            result.appendFormat("Socket Buffer size = %zd events\n",
436444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                                mSocketBufferSize/sizeof(sensors_event_t));
43718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            result.appendFormat("WakeLock Status: %s \n", mWakeLockAcquired ? "acquired" :
43818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                    "not held");
439444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            result.appendFormat("Mode :");
440444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            switch(mCurrentOperatingMode) {
441444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella               case NORMAL:
442444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                   result.appendFormat(" NORMAL\n");
443444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                   break;
444444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella               case RESTRICTED:
445841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                   result.appendFormat(" RESTRICTED : %s\n", mWhiteListedPackage.string());
446444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                   break;
447444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella               case DATA_INJECTION:
448841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella                   result.appendFormat(" DATA_INJECTION : %s\n", mWhiteListedPackage.string());
449444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            }
4504c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella
451e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu            result.appendFormat("%zd active connections\n", mActiveConnections.size());
452444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella            for (size_t i=0 ; i < mActiveConnections.size() ; i++) {
453444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                sp<SensorEventConnection> connection(mActiveConnections[i].promote());
454444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                if (connection != 0) {
455444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    result.appendFormat("Connection Number: %zu \n", i);
456444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    connection->dump(result);
457444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                }
4584c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella            }
45918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella
460e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu            result.appendFormat("%zd direct connections\n", mDirectConnections.size());
461e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu            for (size_t i = 0 ; i < mDirectConnections.size() ; i++) {
462e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu                sp<SensorDirectConnection> connection(mDirectConnections[i].promote());
463e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu                if (connection != nullptr) {
464e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu                    result.appendFormat("Direct connection %zu:\n", i);
465e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu                    connection->dump(result);
466e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu                }
467e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu            }
468e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu
46918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            result.appendFormat("Previous Registrations:\n");
47018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            // Log in the reverse chronological order.
47118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            int currentIndex = (mNextSensorRegIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) %
47218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                SENSOR_REGISTRATIONS_BUF_SIZE;
47318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            const int startIndex = currentIndex;
47418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            do {
47518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                const SensorRegistrationInfo& reg_info = mLastNSensorRegistrations[currentIndex];
47618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                if (SensorRegistrationInfo::isSentinel(reg_info)) {
47718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                    // Ignore sentinel, proceed to next item.
47818d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                    currentIndex = (currentIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) %
47918d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                        SENSOR_REGISTRATIONS_BUF_SIZE;
48018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                    continue;
48118d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                }
48251224681c9a80ff714d40c26d8f465fb1bae17e2Peng Xu                result.appendFormat("%s\n", reg_info.dump().c_str());
48318d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                currentIndex = (currentIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) %
48418d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella                        SENSOR_REGISTRATIONS_BUF_SIZE;
48518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            } while(startIndex != currentIndex);
4864c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
487fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
488fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    write(fd, result.string(), result.size());
489fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return NO_ERROR;
490fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
491fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
4920cc8f809924706c7d683da30605f432635dd5bb6Peng Xu//TODO: move to SensorEventConnection later
4939a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::cleanupAutoDisabledSensorLocked(const sp<SensorEventConnection>& connection,
4944342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        sensors_event_t const* buffer, const int count) {
4954342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    for (int i=0 ; i<count ; i++) {
4964342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        int handle = buffer[i].sensor;
4978493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        if (buffer[i].type == SENSOR_TYPE_META_DATA) {
4988493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            handle = buffer[i].meta_data.sensor;
4998493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        }
5000e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella        if (connection->hasSensor(handle)) {
501755c451c7861a029e26e5f16e319b629169e656dPeng Xu            sp<SensorInterface> si = getSensorInterfaceFromHandle(handle);
5020e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            // If this buffer has an event from a one_shot sensor and this connection is registered
5030e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            // for this particular one_shot sensor, try cleaning up the connection.
504755c451c7861a029e26e5f16e319b629169e656dPeng Xu            if (si != nullptr &&
5050cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                si->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
5060cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                si->autoDisable(connection.get(), handle);
5079a844cf78f09953145200b4074d47589257a408cAravind Akella                cleanupWithoutDisableLocked(connection, handle);
5084342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            }
509a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
5104342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
511a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella   }
5124342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh}
5134342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
51447e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xubool SensorService::threadLoop() {
515a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block    ALOGD("nuSensorService thread starting...");
516fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
517eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu    // each virtual sensor could generate an event per "real" event, that's why we need to size
518eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu    // numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT.  in practice, this is too
519eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu    // aggressive, but guaranteed to be enough.
5200cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    const size_t vcount = mSensors.getVirtualSensors().size();
52190ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian    const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
5220cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    const size_t numEventMax = minBufferSize / (1 + vcount);
52390ed3e8d7883d9c80fb8bf11b1c593bd8b2b39d0Mathias Agopian
524f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    SensorDevice& device(SensorDevice::getInstance());
525fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
5264342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    const int halVersion = device.getHalDeviceVersion();
527fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    do {
5288493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
5298493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        if (count < 0) {
530f5a1230d322c14c42331d0a1536b50c87742973bSteve Block            ALOGE("sensor poll failed (%s)", strerror(-count));
531fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            break;
532fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
53356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
53456ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        // Reset sensors_event_t.flags to zero for all events in the buffer.
53556ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        for (int i = 0; i < count; i++) {
5368493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella             mSensorEventBuffer[i].flags = 0;
53756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella        }
538e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella
539eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu        // Make a copy of the connection vector as some connections may be removed during the course
540eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu        // of this loop (especially when one-shot sensor events are present in the sensor_event
541eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu        // buffer). Promote all connections to StrongPointers before the lock is acquired. If the
542eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu        // destructor of the sp gets called when the lock is acquired, it may result in a deadlock
543eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu        // as ~SensorEventConnection() needs to acquire mLock again for cleanup. So copy all the
544eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu        // strongPointers to a vector before the lock is acquired.
545e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella        SortedVector< sp<SensorEventConnection> > activeConnections;
546b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        populateActiveConnections(&activeConnections);
547eb4d628b69831d533f14c09fd63400f75e69ba76Peng Xu
5489a844cf78f09953145200b4074d47589257a408cAravind Akella        Mutex::Autolock _l(mLock);
5499a844cf78f09953145200b4074d47589257a408cAravind Akella        // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The
5509a844cf78f09953145200b4074d47589257a408cAravind Akella        // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock,
5519a844cf78f09953145200b4074d47589257a408cAravind Akella        // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should
5529a844cf78f09953145200b4074d47589257a408cAravind Akella        // not be interleaved with decrementing SensorEventConnection::mWakeLockRefCount and
5539a844cf78f09953145200b4074d47589257a408cAravind Akella        // releasing the wakelock.
5549a844cf78f09953145200b4074d47589257a408cAravind Akella        bool bufferHasWakeUpEvent = false;
5554342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        for (int i = 0; i < count; i++) {
5568493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            if (isWakeUpSensorEvent(mSensorEventBuffer[i])) {
5579a844cf78f09953145200b4074d47589257a408cAravind Akella                bufferHasWakeUpEvent = true;
5589a844cf78f09953145200b4074d47589257a408cAravind Akella                break;
5594342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            }
5604342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
5614342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
5629a844cf78f09953145200b4074d47589257a408cAravind Akella        if (bufferHasWakeUpEvent && !mWakeLockAcquired) {
563b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            setWakeLockAcquiredLocked(true);
5649a844cf78f09953145200b4074d47589257a408cAravind Akella        }
5658493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        recordLastValueLocked(mSensorEventBuffer, count);
56694e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian
567f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        // handle virtual sensors
568f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        if (count && vcount) {
5698493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            sensors_event_t const * const event = mSensorEventBuffer;
570755c451c7861a029e26e5f16e319b629169e656dPeng Xu            if (!mActiveVirtualSensors.empty()) {
571f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                size_t k = 0;
572984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                SensorFusion& fusion(SensorFusion::getInstance());
573984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                if (fusion.isEnabled()) {
574984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                    for (size_t i=0 ; i<size_t(count) ; i++) {
575984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                        fusion.process(event[i]);
576984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                    }
577984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian                }
578d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) {
579755c451c7861a029e26e5f16e319b629169e656dPeng Xu                    for (int handle : mActiveVirtualSensors) {
580d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                        if (count + k >= minBufferSize) {
581d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                            ALOGE("buffer too small to hold all events: "
582db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn                                    "count=%zd, k=%zu, size=%zu",
583d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                                    count, k, minBufferSize);
584d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                            break;
585d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                        }
586f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                        sensors_event_t out;
587755c451c7861a029e26e5f16e319b629169e656dPeng Xu                        sp<SensorInterface> si = mSensors.getInterface(handle);
588755c451c7861a029e26e5f16e319b629169e656dPeng Xu                        if (si == nullptr) {
589755c451c7861a029e26e5f16e319b629169e656dPeng Xu                            ALOGE("handle %d is not an valid virtual sensor", handle);
590755c451c7861a029e26e5f16e319b629169e656dPeng Xu                            continue;
591755c451c7861a029e26e5f16e319b629169e656dPeng Xu                        }
592755c451c7861a029e26e5f16e319b629169e656dPeng Xu
593d1920ffede9e9bc107104ad94c291ca0f0f18bc3Mathias Agopian                        if (si->process(&out, event[i])) {
5948493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                            mSensorEventBuffer[count + k] = out;
595f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                            k++;
596f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                        }
597f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    }
598f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                }
599f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                if (k) {
600f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    // record the last synthesized values
6018493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    recordLastValueLocked(&mSensorEventBuffer[count], k);
602f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    count += k;
603f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                    // sort the buffer by time-stamps
6048493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    sortEventBuffer(mSensorEventBuffer, count);
605f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                }
606f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            }
607f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        }
608f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
6094342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // handle backward compatibility for RotationVector sensor
6104342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) {
6114342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            for (int i = 0; i < count; i++) {
6128493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                if (mSensorEventBuffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) {
6134342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                    // All the 4 components of the quaternion should be available
6144342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                    // No heading accuracy. Set it to -1
6158493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    mSensorEventBuffer[i].data[4] = -1;
6168493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                }
6178493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            }
6188493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        }
6198493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella
6208493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        for (int i = 0; i < count; ++i) {
6210cc8f809924706c7d683da30605f432635dd5bb6Peng Xu            // Map flush_complete_events in the buffer to SensorEventConnections which called flush
6220cc8f809924706c7d683da30605f432635dd5bb6Peng Xu            // on the hardware sensor. mapFlushEventsToConnections[i] will be the
6230cc8f809924706c7d683da30605f432635dd5bb6Peng Xu            // SensorEventConnection mapped to the corresponding flush_complete_event in
6240cc8f809924706c7d683da30605f432635dd5bb6Peng Xu            // mSensorEventBuffer[i] if such a mapping exists (NULL otherwise).
6258493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            mMapFlushEventsToConnections[i] = NULL;
6268493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella            if (mSensorEventBuffer[i].type == SENSOR_TYPE_META_DATA) {
6278493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                const int sensor_handle = mSensorEventBuffer[i].meta_data.sensor;
6288493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                SensorRecord* rec = mActiveSensors.valueFor(sensor_handle);
6298493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                if (rec != NULL) {
6308493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    mMapFlushEventsToConnections[i] = rec->getFirstPendingFlushConnection();
6318493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                    rec->removeFirstPendingFlushConnection();
6324342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh                }
6334342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            }
6342576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
6352576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            // handle dynamic sensor meta events, process registration and unregistration of dynamic
6362576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            // sensor based on content of event.
6372576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            if (mSensorEventBuffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META) {
6382576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                if (mSensorEventBuffer[i].dynamic_sensor_meta.connected) {
6392576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    int handle = mSensorEventBuffer[i].dynamic_sensor_meta.handle;
6402576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    const sensor_t& dynamicSensor =
6412576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                            *(mSensorEventBuffer[i].dynamic_sensor_meta.sensor);
6422576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    ALOGI("Dynamic sensor handle 0x%x connected, type %d, name %s",
6432576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                          handle, dynamicSensor.type, dynamicSensor.name);
6442576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
6450cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                    if (mSensors.isNewHandle(handle)) {
6466a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                        const auto& uuid = mSensorEventBuffer[i].dynamic_sensor_meta.uuid;
64747e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu                        sensor_t s = dynamicSensor;
64847e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu                        // make sure the dynamic sensor flag is set
64947e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu                        s.flags |= DYNAMIC_SENSOR_MASK;
65047e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu                        // force the handle to be consistent
65147e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu                        s.handle = handle;
6526a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
6536a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                        SensorInterface *si = new HardwareSensor(s, uuid);
65447e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu
6550cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                        // This will release hold on dynamic sensor meta, so it should be called
6560cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                        // after Sensor object is created.
65747e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu                        device.handleDynamicSensorConnection(handle, true /*connected*/);
6586a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                        registerDynamicSensorLocked(si);
65947e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu                    } else {
66047e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu                        ALOGE("Handle %d has been used, cannot use again before reboot.", handle);
66147e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu                    }
6622576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                } else {
6632576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    int handle = mSensorEventBuffer[i].dynamic_sensor_meta.handle;
6642576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    ALOGI("Dynamic sensor handle 0x%x disconnected", handle);
6652576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
6662576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    device.handleDynamicSensorConnection(handle, false /*connected*/);
6676a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                    if (!unregisterDynamicSensorLocked(handle)) {
6682576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                        ALOGE("Dynamic sensor release error.");
6692576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    }
6702576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
6712576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    size_t numConnections = activeConnections.size();
6722576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    for (size_t i=0 ; i < numConnections; ++i) {
6732576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                        if (activeConnections[i] != NULL) {
6742576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                            activeConnections[i]->removeSensor(handle);
6752576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                        }
6762576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                    }
6772576cb63b3fe1592f54816625036566b9eb0793aPeng Xu                }
6782576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            }
6794342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
6804342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
6812576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
6829a844cf78f09953145200b4074d47589257a408cAravind Akella        // Send our events to clients. Check the state of wake lock for each client and release the
6839a844cf78f09953145200b4074d47589257a408cAravind Akella        // lock if none of the clients need it.
6849a844cf78f09953145200b4074d47589257a408cAravind Akella        bool needsWakeLock = false;
6858493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        size_t numConnections = activeConnections.size();
6868493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        for (size_t i=0 ; i < numConnections; ++i) {
687e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella            if (activeConnections[i] != 0) {
688e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella                activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,
6898493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                        mMapFlushEventsToConnections);
690e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella                needsWakeLock |= activeConnections[i]->needsWakeLock();
6918493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                // If the connection has one-shot sensors, it may be cleaned up after first trigger.
6928493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                // Early check for one-shot sensors.
693e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella                if (activeConnections[i]->hasOneShotSensors()) {
694e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella                    cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer,
695e148bc29c27ae7a346fa686fdda6425ba202d97aAravind Akella                            count);
6968493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella                }
697fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            }
698fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
6994342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
7009a844cf78f09953145200b4074d47589257a408cAravind Akella        if (mWakeLockAcquired && !needsWakeLock) {
701b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            setWakeLockAcquiredLocked(false);
7029a844cf78f09953145200b4074d47589257a408cAravind Akella        }
7038493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella    } while (!Thread::exitPending());
704fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
7053c20fbed7f3a916ced10f2ed5a272271b7d81edeSteve Block    ALOGW("Exiting SensorService::threadLoop => aborting...");
7061a62301fc58cd2af18239b0415813461bf5fc41bMathias Agopian    abort();
707fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return false;
708fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
709fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
71056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellasp<Looper> SensorService::getLooper() const {
71156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    return mLooper;
71256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella}
71356ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
714b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::resetAllWakeLockRefCounts() {
715b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    SortedVector< sp<SensorEventConnection> > activeConnections;
716b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    populateActiveConnections(&activeConnections);
717b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    {
718b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        Mutex::Autolock _l(mLock);
719b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        for (size_t i=0 ; i < activeConnections.size(); ++i) {
720b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            if (activeConnections[i] != 0) {
721b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella                activeConnections[i]->resetWakeLockRefCount();
722b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            }
723b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        }
724b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        setWakeLockAcquiredLocked(false);
725b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    }
726b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
727b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
728b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::setWakeLockAcquiredLocked(bool acquire) {
729b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    if (acquire) {
730b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        if (!mWakeLockAcquired) {
731b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
732b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            mWakeLockAcquired = true;
733b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        }
734b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        mLooper->wake();
735b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    } else {
736b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        if (mWakeLockAcquired) {
737b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            release_wake_lock(WAKE_LOCK_NAME);
738b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            mWakeLockAcquired = false;
739b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        }
740b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    }
741b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
742b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
743b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellabool SensorService::isWakeLockAcquired() {
744b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    Mutex::Autolock _l(mLock);
745b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    return mWakeLockAcquired;
746b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
747b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
74856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akellabool SensorService::SensorEventAckReceiver::threadLoop() {
74956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    ALOGD("new thread SensorEventAckReceiver");
750b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    sp<Looper> looper = mService->getLooper();
75156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    do {
752b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        bool wakeLockAcquired = mService->isWakeLockAcquired();
753b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        int timeout = -1;
754b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        if (wakeLockAcquired) timeout = 5000;
755b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        int ret = looper->pollOnce(timeout);
756b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        if (ret == ALOOPER_POLL_TIMEOUT) {
757b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella           mService->resetAllWakeLockRefCounts();
758b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        }
75956ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    } while(!Thread::exitPending());
76056ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    return false;
76156ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella}
76256ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
7639a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::recordLastValueLocked(
7644b84704b97300eff3ebfab85652e64d54149d205Aravind Akella        const sensors_event_t* buffer, size_t count) {
7654b84704b97300eff3ebfab85652e64d54149d205Aravind Akella    for (size_t i = 0; i < count; i++) {
7662576cb63b3fe1592f54816625036566b9eb0793aPeng Xu        if (buffer[i].type == SENSOR_TYPE_META_DATA ||
7672576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            buffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META ||
7686a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu            buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO) {
7692576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            continue;
7702576cb63b3fe1592f54816625036566b9eb0793aPeng Xu        }
7712576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
7726a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu        auto logger = mRecentEvent.find(buffer[i].sensor);
7736a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu        if (logger != mRecentEvent.end()) {
7746a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu            logger->second->addEvent(buffer[i]);
77594e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian        }
77694e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian    }
77794e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian}
77894e8f6813f3fb2beaa9bcbfb1ad9b4ae2eb46949Mathias Agopian
77947e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xuvoid SensorService::sortEventBuffer(sensors_event_t* buffer, size_t count) {
780f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    struct compar {
781f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        static int cmp(void const* lhs, void const* rhs) {
782f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            sensors_event_t const* l = static_cast<sensors_event_t const*>(lhs);
783f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            sensors_event_t const* r = static_cast<sensors_event_t const*>(rhs);
784a5c106a4f0afcf061728a1cb7c8c3b908728575dMathias Agopian            return l->timestamp - r->timestamp;
785f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        }
786f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    };
787f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    qsort(buffer, count, sizeof(sensors_event_t), compar::cmp);
788f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
789f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
7905d2707214dfb97bd8dfcc6620be36841d3c82420Mathias AgopianString8 SensorService::getSensorName(int handle) const {
7910cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    return mSensors.getName(handle);
7925d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian}
7935d2707214dfb97bd8dfcc6620be36841d3c82420Mathias Agopian
794b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akellabool SensorService::isVirtualSensor(int handle) const {
795755c451c7861a029e26e5f16e319b629169e656dPeng Xu    sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
796755c451c7861a029e26e5f16e319b629169e656dPeng Xu    return sensor != nullptr && sensor->isVirtual();
797b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella}
798b4099e77ec2bf8e9d4259ff30f0cb1d621deed91Aravind Akella
7999a844cf78f09953145200b4074d47589257a408cAravind Akellabool SensorService::isWakeUpSensorEvent(const sensors_event_t& event) const {
8007869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan    int handle = event.sensor;
8017869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan    if (event.type == SENSOR_TYPE_META_DATA) {
8027869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan        handle = event.meta_data.sensor;
8037869e224aaaf717b5ab86df00b60fd5be5a0996cSean Wan    }
804755c451c7861a029e26e5f16e319b629169e656dPeng Xu    sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
805755c451c7861a029e26e5f16e319b629169e656dPeng Xu    return sensor != nullptr && sensor->getSensor().isWakeUpSensor();
8069a844cf78f09953145200b4074d47589257a408cAravind Akella}
8079a844cf78f09953145200b4074d47589257a408cAravind Akella
80853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiserint32_t SensorService::getIdFromUuid(const Sensor::uuid_t &uuid) const {
80953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    if ((uuid.i64[0] == 0) && (uuid.i64[1] == 0)) {
81053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        // UUID is not supported for this device.
81153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        return 0;
81253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    }
81353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    if ((uuid.i64[0] == INT64_C(~0)) && (uuid.i64[1] == INT64_C(~0))) {
81453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        // This sensor can be uniquely identified in the system by
81553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        // the combination of its type and name.
81653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        return -1;
81753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    }
81853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser
81953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    // We have a dynamic sensor.
82053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser
82153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    if (!sHmacGlobalKeyIsValid) {
82253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        // Rather than risk exposing UUIDs, we cripple dynamic sensors.
82353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        ALOGW("HMAC key failure; dynamic sensor getId() will be wrong.");
82453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        return 0;
82553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    }
82653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser
82753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    // We want each app author/publisher to get a different ID, so that the
82853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    // same dynamic sensor cannot be tracked across apps by multiple
82953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    // authors/publishers.  So we use both our UUID and our User ID.
83053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    // Note potential confusion:
83153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    //     UUID => Universally Unique Identifier.
83253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    //     UID  => User Identifier.
83353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    // We refrain from using "uid" except as needed by API to try to
83453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    // keep this distinction clear.
83553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser
83653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    auto appUserId = IPCThreadState::self()->getCallingUid();
83753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    uint8_t uuidAndApp[sizeof(uuid) + sizeof(appUserId)];
83853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    memcpy(uuidAndApp, &uuid, sizeof(uuid));
83953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    memcpy(uuidAndApp + sizeof(uuid), &appUserId, sizeof(appUserId));
84053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser
84153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    // Now we use our key on our UUID/app combo to get the hash.
84253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    uint8_t hash[EVP_MAX_MD_SIZE];
84353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    unsigned int hashLen;
84453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    if (HMAC(EVP_sha256(),
84553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser             sHmacGlobalKey, sizeof(sHmacGlobalKey),
84653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser             uuidAndApp, sizeof(uuidAndApp),
84753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser             hash, &hashLen) == nullptr) {
84853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        // Rather than risk exposing UUIDs, we cripple dynamic sensors.
84953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        ALOGW("HMAC failure; dynamic sensor getId() will be wrong.");
85053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        return 0;
85153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    }
85253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser
85353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    int32_t id = 0;
85453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    if (hashLen < sizeof(id)) {
85553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        // We never expect this case, but out of paranoia, we handle it.
85653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        // Our 'id' length is already quite small, we don't want the
85753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        // effective length of it to be even smaller.
85853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        // Rather than risk exposing UUIDs, we cripple dynamic sensors.
85953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        ALOGW("HMAC insufficient; dynamic sensor getId() will be wrong.");
86053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        return 0;
86153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    }
86253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser
86353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    // This is almost certainly less than all of 'hash', but it's as secure
86453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    // as we can be with our current 'id' length.
86553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    memcpy(&id, hash, sizeof(id));
86653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser
86753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    // Note at the beginning of the function that we return the values of
86853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    // 0 and -1 to represent special cases.  As a result, we can't return
86953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    // those as dynamic sensor IDs.  If we happened to hash to one of those
87053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    // values, we change 'id' so we report as a dynamic sensor, and not as
87153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    // one of those special cases.
87253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    if (id == -1) {
87353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        id = -2;
87453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    } else if (id == 0) {
87553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        id = 1;
87653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    }
87753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    return id;
87853ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser}
87953ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser
88053ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiservoid SensorService::makeUuidsIntoIdsForSensorList(Vector<Sensor> &sensorList) const {
88153ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    for (auto &sensor : sensorList) {
88253ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        int32_t id = getIdFromUuid(sensor.getUuid());
88353ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser        sensor.setId(id);
88453ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    }
88553ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser}
88653ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser
8872c588c536090ea3e7e80db0e5031935b6026814cNick VaccaroVector<Sensor> SensorService::getSensorList(const String16& /* opPackageName */) {
88833264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian    char value[PROPERTY_VALUE_MAX];
88933264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian    property_get("debug.sensors", value, "0");
890700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    const Vector<Sensor>& initialSensorList = (atoi(value)) ?
8910cc8f809924706c7d683da30605f432635dd5bb6Peng Xu            mSensors.getUserDebugSensors() : mSensors.getUserSensors();
892700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    Vector<Sensor> accessibleSensorList;
893700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    for (size_t i = 0; i < initialSensorList.size(); i++) {
894700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        Sensor sensor = initialSensorList[i];
8952c588c536090ea3e7e80db0e5031935b6026814cNick Vaccaro        accessibleSensorList.add(sensor);
89633264868ba0aaccb9d4b5e5a067a79a43633f6ecMathias Agopian    }
89753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    makeUuidsIntoIdsForSensorList(accessibleSensorList);
898700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    return accessibleSensorList;
899fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
900fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
90147e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng XuVector<Sensor> SensorService::getDynamicSensorList(const String16& opPackageName) {
9022576cb63b3fe1592f54816625036566b9eb0793aPeng Xu    Vector<Sensor> accessibleSensorList;
9030cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    mSensors.forEachSensor(
9040cc8f809924706c7d683da30605f432635dd5bb6Peng Xu            [&opPackageName, &accessibleSensorList] (const Sensor& sensor) -> bool {
905755c451c7861a029e26e5f16e319b629169e656dPeng Xu                if (sensor.isDynamicSensor()) {
906755c451c7861a029e26e5f16e319b629169e656dPeng Xu                    if (canAccessSensor(sensor, "getDynamicSensorList", opPackageName)) {
907755c451c7861a029e26e5f16e319b629169e656dPeng Xu                        accessibleSensorList.add(sensor);
908755c451c7861a029e26e5f16e319b629169e656dPeng Xu                    } else {
909755c451c7861a029e26e5f16e319b629169e656dPeng Xu                        ALOGI("Skipped sensor %s because it requires permission %s and app op %" PRId32,
910755c451c7861a029e26e5f16e319b629169e656dPeng Xu                              sensor.getName().string(),
911755c451c7861a029e26e5f16e319b629169e656dPeng Xu                              sensor.getRequiredPermission().string(),
912755c451c7861a029e26e5f16e319b629169e656dPeng Xu                              sensor.getRequiredAppOp());
913755c451c7861a029e26e5f16e319b629169e656dPeng Xu                    }
9140cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                }
9150cc8f809924706c7d683da30605f432635dd5bb6Peng Xu                return true;
9160cc8f809924706c7d683da30605f432635dd5bb6Peng Xu            });
91753ca2e00c6f2a71b93c8e3c8e85aeeb03c5bd06dGreg Kaiser    makeUuidsIntoIdsForSensorList(accessibleSensorList);
9182576cb63b3fe1592f54816625036566b9eb0793aPeng Xu    return accessibleSensorList;
9192576cb63b3fe1592f54816625036566b9eb0793aPeng Xu}
9202576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
921a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellasp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName,
922b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        int requestedMode, const String16& opPackageName) {
923a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    // Only 2 modes supported for a SensorEventConnection ... NORMAL and DATA_INJECTION.
924a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    if (requestedMode != NORMAL && requestedMode != DATA_INJECTION) {
925a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        return NULL;
926a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    }
927a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
928a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    Mutex::Autolock _l(mLock);
929841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    // To create a client in DATA_INJECTION mode to inject data, SensorService should already be
930841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    // operating in DI mode.
931841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    if (requestedMode == DATA_INJECTION) {
932841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella        if (mCurrentOperatingMode != DATA_INJECTION) return NULL;
933841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella        if (!isWhiteListedPackage(packageName)) return NULL;
934841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    }
935841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella
9365307d17fe33fc26eeeacd6339a9fbfe96cf56873Mathias Agopian    uid_t uid = IPCThreadState::self()->getCallingUid();
93758d450af6d956538e938661bbe7aef9f32e50badPeng Xu    pid_t pid = IPCThreadState::self()->getCallingPid();
93858d450af6d956538e938661bbe7aef9f32e50badPeng Xu
93958d450af6d956538e938661bbe7aef9f32e50badPeng Xu    String8 connPackageName =
94058d450af6d956538e938661bbe7aef9f32e50badPeng Xu            (packageName == "") ? String8::format("unknown_package_pid_%d", pid) : packageName;
94158d450af6d956538e938661bbe7aef9f32e50badPeng Xu    String16 connOpPackageName =
94258d450af6d956538e938661bbe7aef9f32e50badPeng Xu            (opPackageName == String16("")) ? String16(connPackageName) : opPackageName;
94358d450af6d956538e938661bbe7aef9f32e50badPeng Xu    sp<SensorEventConnection> result(new SensorEventConnection(this, uid, connPackageName,
94458d450af6d956538e938661bbe7aef9f32e50badPeng Xu            requestedMode == DATA_INJECTION, connOpPackageName));
945a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    if (requestedMode == DATA_INJECTION) {
946a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        if (mActiveConnections.indexOf(result) < 0) {
947a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella            mActiveConnections.add(result);
948a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        }
949a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        // Add the associated file descriptor to the Looper for polling whenever there is data to
950a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        // be injected.
951a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella        result->updateLooperRegistration(mLooper);
952a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    }
953fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return result;
954fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
955fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
956841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akellaint SensorService::isDataInjectionEnabled() {
957a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    Mutex::Autolock _l(mLock);
958841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    return (mCurrentOperatingMode == DATA_INJECTION);
959a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella}
960a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
961e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xusp<ISensorEventConnection> SensorService::createSensorDirectConnection(
962e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        const String16& opPackageName, uint32_t size, int32_t type, int32_t format,
963e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        const native_handle *resource) {
964e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    Mutex::Autolock _l(mLock);
965e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu
966e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    struct sensors_direct_mem_t mem = {
967e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        .type = type,
968e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        .format = format,
969e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        .size = size,
970e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        .handle = resource,
971e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    };
972e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    uid_t uid = IPCThreadState::self()->getCallingUid();
973e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu
974e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    if (mem.handle == nullptr) {
975e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        ALOGE("Failed to clone resource handle");
976e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        return nullptr;
977e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    }
978e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu
979e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    // check format
980e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    if (format != SENSOR_DIRECT_FMT_SENSORS_EVENT) {
981e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        ALOGE("Direct channel format %d is unsupported!", format);
982e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        return nullptr;
983e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    }
984e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu
985e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    // check for duplication
986e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    for (auto &i : mDirectConnections) {
987e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        sp<SensorDirectConnection> connection(i.promote());
988e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        if (connection != nullptr && connection->isEquivalent(&mem)) {
989f88e2b95b2cd6238f6758ef6a180fbd277f06ff2Peng Xu            ALOGE("Duplicate create channel request for the same share memory");
990e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu            return nullptr;
991e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        }
992e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    }
993e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu
994e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    // check specific to memory type
995e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    switch(type) {
996e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        case SENSOR_DIRECT_MEM_TYPE_ASHMEM: { // channel backed by ashmem
9978b1517ced6a294f479e261961d03c7356dec0838Brian Duddie            if (resource->numFds < 1) {
9988b1517ced6a294f479e261961d03c7356dec0838Brian Duddie                ALOGE("Ashmem direct channel requires a memory region to be supplied");
9998b1517ced6a294f479e261961d03c7356dec0838Brian Duddie                android_errorWriteLog(0x534e4554, "70986337");  // SafetyNet
10008b1517ced6a294f479e261961d03c7356dec0838Brian Duddie                return nullptr;
10018b1517ced6a294f479e261961d03c7356dec0838Brian Duddie            }
1002e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu            int fd = resource->data[0];
1003e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu            int size2 = ashmem_get_size_region(fd);
1004e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu            // check size consistency
10058b1517ced6a294f479e261961d03c7356dec0838Brian Duddie            if (size2 < static_cast<int64_t>(size)) {
1006f88e2b95b2cd6238f6758ef6a180fbd277f06ff2Peng Xu                ALOGE("Ashmem direct channel size %" PRIu32 " greater than shared memory size %d",
1007f88e2b95b2cd6238f6758ef6a180fbd277f06ff2Peng Xu                      size, size2);
1008e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu                return nullptr;
1009e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu            }
1010e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu            break;
1011e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        }
1012e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
1013f88e2b95b2cd6238f6758ef6a180fbd277f06ff2Peng Xu            // no specific checks for gralloc
1014e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu            break;
1015e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        default:
1016e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu            ALOGE("Unknown direct connection memory type %d", type);
1017e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu            return nullptr;
1018e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    }
1019e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu
1020e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    native_handle_t *clone = native_handle_clone(resource);
1021e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    if (!clone) {
1022e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        return nullptr;
1023e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    }
1024e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu
1025e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    SensorDirectConnection* conn = nullptr;
1026e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    SensorDevice& dev(SensorDevice::getInstance());
1027e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    int channelHandle = dev.registerDirectChannel(&mem);
1028e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu
1029e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    if (channelHandle <= 0) {
1030e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        ALOGE("SensorDevice::registerDirectChannel returns %d", channelHandle);
1031e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    } else {
1032e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        mem.handle = clone;
1033e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        conn = new SensorDirectConnection(this, uid, &mem, channelHandle, opPackageName);
1034e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    }
1035e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu
1036e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    if (conn == nullptr) {
1037e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        native_handle_close(clone);
1038e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        native_handle_delete(clone);
1039e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    } else {
1040e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        // add to list of direct connections
1041e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        // sensor service should never hold pointer or sp of SensorDirectConnection object.
1042e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        mDirectConnections.add(wp<SensorDirectConnection>(conn));
1043e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    }
1044e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    return conn;
1045e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu}
1046e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu
1047dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xuint SensorService::setOperationParameter(
104888711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov            int32_t handle, int32_t type,
104988711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov            const Vector<float> &floats, const Vector<int32_t> &ints) {
1050dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu    Mutex::Autolock _l(mLock);
1051dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu
105288711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov    if (!checkCallingPermission(sLocationHardwarePermission, nullptr, nullptr)) {
1053dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu        return PERMISSION_DENIED;
1054dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu    }
1055dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu
1056dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu    bool isFloat = true;
105788711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov    bool isCustom = false;
1058dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu    size_t expectSize = INT32_MAX;
1059dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu    switch (type) {
1060dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu        case AINFO_LOCAL_GEOMAGNETIC_FIELD:
1061dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu            isFloat = true;
1062dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu            expectSize = 3;
1063dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu            break;
1064dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu        case AINFO_LOCAL_GRAVITY:
1065dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu            isFloat = true;
1066dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu            expectSize = 1;
1067dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu            break;
1068dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu        case AINFO_DOCK_STATE:
1069dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu        case AINFO_HIGH_PERFORMANCE_MODE:
1070dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu        case AINFO_MAGNETIC_FIELD_CALIBRATION:
1071dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu            isFloat = false;
1072dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu            expectSize = 1;
1073dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu            break;
1074dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu        default:
107588711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov            // CUSTOM events must only contain float data; it may have variable size
107688711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov            if (type < AINFO_CUSTOM_START || type >= AINFO_DEBUGGING_START ||
107788711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov                    ints.size() ||
107888711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov                    sizeof(additional_info_event_t::data_float)/sizeof(float) < floats.size() ||
107988711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov                    handle < 0) {
108088711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov                return BAD_VALUE;
108188711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov            }
108288711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov            isFloat = true;
108388711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov            isCustom = true;
108488711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov            expectSize = floats.size();
108588711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov            break;
108688711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov    }
108788711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov
108888711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov    if (!isCustom && handle != -1) {
108988711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov        return BAD_VALUE;
1090dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu    }
1091dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu
1092dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu    // three events: first one is begin tag, last one is end tag, the one in the middle
1093dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu    // is the payload.
1094dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu    sensors_event_t event[3];
1095dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu    int64_t timestamp = elapsedRealtimeNano();
1096dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu    for (sensors_event_t* i = event; i < event + 3; i++) {
1097dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu        *i = (sensors_event_t) {
1098dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu            .version = sizeof(sensors_event_t),
109988711e8755e729682f32ee304d1cf0f60a3642bfAlexey Polyudov            .sensor = handle,
1100dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu            .type = SENSOR_TYPE_ADDITIONAL_INFO,
1101dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu            .timestamp = timestamp++,
1102dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu            .additional_info = (additional_info_event_t) {
1103dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu                .serial = 0
1104dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu            }
1105dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu        };
1106dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu    }
1107dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu
1108dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu    event[0].additional_info.type = AINFO_BEGIN;
1109dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu    event[1].additional_info.type = type;
1110dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu    event[2].additional_info.type = AINFO_END;
1111dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu
1112dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu    if (isFloat) {
1113dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu        if (floats.size() != expectSize) {
1114dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu            return BAD_VALUE;
1115dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu        }
1116dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu        for (size_t i = 0; i < expectSize; ++i) {
1117dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu            event[1].additional_info.data_float[i] = floats[i];
1118dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu        }
1119dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu    } else {
1120dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu        if (ints.size() != expectSize) {
1121dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu            return BAD_VALUE;
1122dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu        }
1123dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu        for (size_t i = 0; i < expectSize; ++i) {
1124dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu            event[1].additional_info.data_int32[i] = ints[i];
1125dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu        }
1126dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu    }
1127dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu
1128dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu    SensorDevice& dev(SensorDevice::getInstance());
1129dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu    for (sensors_event_t* i = event; i < event + 3; i++) {
1130dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu        int ret = dev.injectSensorData(i);
1131dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu        if (ret != NO_ERROR) {
1132dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu            return ret;
1133dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu        }
1134dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu    }
1135dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu    return NO_ERROR;
1136dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu}
1137dd5c5cb3b8f3df9b458dff74e247b9a542befee7Peng Xu
1138a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatus_t SensorService::resetToNormalMode() {
1139a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    Mutex::Autolock _l(mLock);
1140a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    return resetToNormalModeLocked();
1141a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella}
1142a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
1143a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatus_t SensorService::resetToNormalModeLocked() {
1144a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    SensorDevice& dev(SensorDevice::getInstance());
1145a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    status_t err = dev.setMode(NORMAL);
1146bfac17eed90d410de51413ef2484f79fb0e241e2Aniroop Mathur    if (err == NO_ERROR) {
1147bfac17eed90d410de51413ef2484f79fb0e241e2Aniroop Mathur        mCurrentOperatingMode = NORMAL;
1148bfac17eed90d410de51413ef2484f79fb0e241e2Aniroop Mathur        dev.enableAllSensors();
1149bfac17eed90d410de51413ef2484f79fb0e241e2Aniroop Mathur    }
1150a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella    return err;
1151a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella}
1152a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
115347e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xuvoid SensorService::cleanupConnection(SensorEventConnection* c) {
1154fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    Mutex::Autolock _l(mLock);
1155db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian    const wp<SensorEventConnection> connection(c);
11567c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    size_t size = mActiveSensors.size();
1157db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn    ALOGD_IF(DEBUG_CONNECTIONS, "%zu active sensors", size);
11587c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    for (size_t i=0 ; i<size ; ) {
1159db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        int handle = mActiveSensors.keyAt(i);
1160db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        if (c->hasSensor(handle)) {
1161db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn            ALOGD_IF(DEBUG_CONNECTIONS, "%zu: disabling handle=0x%08x", i, handle);
1162755c451c7861a029e26e5f16e319b629169e656dPeng Xu            sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
1163755c451c7861a029e26e5f16e319b629169e656dPeng Xu            if (sensor != nullptr) {
1164db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian                sensor->activate(c, false);
1165755c451c7861a029e26e5f16e319b629169e656dPeng Xu            } else {
1166755c451c7861a029e26e5f16e319b629169e656dPeng Xu                ALOGE("sensor interface of handle=0x%08x is null!", handle);
1167f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            }
11688a96955c8e14db40b16164236830fc9506a00872Aravind Akella            c->removeSensor(handle);
1169db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        }
1170db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        SensorRecord* rec = mActiveSensors.valueAt(i);
1171db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn        ALOGE_IF(!rec, "mActiveSensors[%zu] is null (handle=0x%08x)!", i, handle);
1172a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block        ALOGD_IF(DEBUG_CONNECTIONS,
1173db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn                "removing connection %p for sensor[%zu].handle=0x%08x",
1174a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian                c, i, handle);
1175a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian
1176db5b4bce9e65ec9c2c7762b601297e4abadbc22aMathias Agopian        if (rec && rec->removeConnection(connection)) {
1177a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block            ALOGD_IF(DEBUG_CONNECTIONS, "... and it was the last connection");
11787c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            mActiveSensors.removeItemsAt(i, 1);
1179755c451c7861a029e26e5f16e319b629169e656dPeng Xu            mActiveVirtualSensors.erase(handle);
11807c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            delete rec;
11817c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            size--;
11827c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian        } else {
11837c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            i++;
1184fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
1185fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
11868a96955c8e14db40b16164236830fc9506a00872Aravind Akella    c->updateLooperRegistration(mLooper);
11877c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    mActiveConnections.remove(connection);
1188787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian    BatteryService::cleanup(c->getUid());
11899a844cf78f09953145200b4074d47589257a408cAravind Akella    if (c->needsWakeLock()) {
11909a844cf78f09953145200b4074d47589257a408cAravind Akella        checkWakeLockStateLocked();
11919a844cf78f09953145200b4074d47589257a408cAravind Akella    }
11924f707f8b3da68d3055db895da9ae5216cc4f483aPeng Xu
11934f707f8b3da68d3055db895da9ae5216cc4f483aPeng Xu    SensorDevice& dev(SensorDevice::getInstance());
11944f707f8b3da68d3055db895da9ae5216cc4f483aPeng Xu    dev.notifyConnectionDestroyed(c);
1195fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1196fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1197e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xuvoid SensorService::cleanupConnection(SensorDirectConnection* c) {
1198e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    Mutex::Autolock _l(mLock);
1199e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu
1200e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    SensorDevice& dev(SensorDevice::getInstance());
1201e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    dev.unregisterDirectChannel(c->getHalChannelHandle());
1202e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    mDirectConnections.remove(c);
1203e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu}
1204e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu
1205755c451c7861a029e26e5f16e319b629169e656dPeng Xusp<SensorInterface> SensorService::getSensorInterfaceFromHandle(int handle) const {
12060cc8f809924706c7d683da30605f432635dd5bb6Peng Xu    return mSensors.getInterface(handle);
120747e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu}
120847e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu
1209fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopianstatus_t SensorService::enable(const sp<SensorEventConnection>& connection,
1210b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags,
121147e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu        const String16& opPackageName) {
121250df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian    if (mInitCheck != NO_ERROR)
121350df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian        return mInitCheck;
121450df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
1215755c451c7861a029e26e5f16e319b629169e656dPeng Xu    sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
1216755c451c7861a029e26e5f16e319b629169e656dPeng Xu    if (sensor == nullptr ||
1217755c451c7861a029e26e5f16e319b629169e656dPeng Xu        !canAccessSensor(sensor->getSensor(), "Tried enabling", opPackageName)) {
1218700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return BAD_VALUE;
1219700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
1220700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
1221ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    Mutex::Autolock _l(mLock);
1222e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    if (mCurrentOperatingMode != NORMAL
1223841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella           && !isWhiteListedPackage(connection->getPackageName())) {
12244949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        return INVALID_OPERATION;
12254949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    }
12264949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
12274342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    SensorRecord* rec = mActiveSensors.valueFor(handle);
12284342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (rec == 0) {
12294342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        rec = new SensorRecord(connection);
12304342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        mActiveSensors.add(handle, rec);
12314342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (sensor->isVirtual()) {
1232755c451c7861a029e26e5f16e319b629169e656dPeng Xu            mActiveVirtualSensors.emplace(handle);
12333560fb24b668675627934356f210d84d19bf4e56Mathias Agopian        }
12344342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    } else {
12354342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (rec->addConnection(connection)) {
12369a844cf78f09953145200b4074d47589257a408cAravind Akella            // this sensor is already activated, but we are adding a connection that uses it.
12379a844cf78f09953145200b4074d47589257a408cAravind Akella            // Immediately send down the last known value of the requested sensor if it's not a
12384342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            // "continuous" sensor.
12390e025c5af365e45e02cb75c1d46b46c7f4cd44cbAravind Akella            if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ON_CHANGE) {
12409a844cf78f09953145200b4074d47589257a408cAravind Akella                // NOTE: The wake_up flag of this event may get set to
12419a844cf78f09953145200b4074d47589257a408cAravind Akella                // WAKE_UP_SENSOR_EVENT_NEEDS_ACK if this is a wake_up event.
12426a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
12436a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                auto logger = mRecentEvent.find(handle);
12446a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                if (logger != mRecentEvent.end()) {
1245444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    sensors_event_t event;
1246444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    // It is unlikely that this buffer is empty as the sensor is already active.
1247444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    // One possible corner case may be two applications activating an on-change
1248444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                    // sensor at the same time.
12496a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                    if(logger->second->populateLastEvent(&event)) {
1250444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        event.sensor = handle;
1251444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        if (event.version == sizeof(sensors_event_t)) {
1252444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                            if (isWakeUpSensorEvent(event) && !mWakeLockAcquired) {
1253444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                                setWakeLockAcquiredLocked(true);
1254444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                            }
1255444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                            connection->sendEvents(&event, 1, NULL);
1256444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                            if (!connection->needsWakeLock() && mWakeLockAcquired) {
1257444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                                checkWakeLockStateLocked();
1258444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                            }
1259444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella                        }
12609a844cf78f09953145200b4074d47589257a408cAravind Akella                    }
1261f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                }
12627c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian            }
1263fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
1264fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    }
12654342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
12664342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (connection->addSensor(handle)) {
12674342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        BatteryService::enableSensor(connection->getUid(), handle);
12684342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // the sensor was added (which means it wasn't already there)
12694342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        // so, see if this connection becomes active
12704342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        if (mActiveConnections.indexOf(connection) < 0) {
12714342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            mActiveConnections.add(connection);
12724342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        }
12734342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    } else {
12744342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        ALOGW("sensor %08x already enabled in connection %p (ignoring)",
12754342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh            handle, connection.get());
12764342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
12774342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
1278d8a5ce39101f569f6bdab696ed02623e5aff7451Aniroop Mathur    // Check maximum delay for the sensor.
1279663720b29f412756b8599897df9f8e32eb930be2Jim Kaye    nsecs_t maxDelayNs = sensor->getSensor().getMaxDelay() * 1000LL;
1280d8a5ce39101f569f6bdab696ed02623e5aff7451Aniroop Mathur    if (maxDelayNs > 0 && (samplingPeriodNs > maxDelayNs)) {
1281d8a5ce39101f569f6bdab696ed02623e5aff7451Aniroop Mathur        samplingPeriodNs = maxDelayNs;
1282d8a5ce39101f569f6bdab696ed02623e5aff7451Aniroop Mathur    }
1283d8a5ce39101f569f6bdab696ed02623e5aff7451Aniroop Mathur
1284724d91d778e71c8186399f4955de14b54812b3edAravind Akella    nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
1285724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (samplingPeriodNs < minDelayNs) {
1286724d91d778e71c8186399f4955de14b54812b3edAravind Akella        samplingPeriodNs = minDelayNs;
1287724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
1288724d91d778e71c8186399f4955de14b54812b3edAravind Akella
12896c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d"
12906c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                                "rate=%" PRId64 " timeout== %" PRId64"",
1291724d91d778e71c8186399f4955de14b54812b3edAravind Akella             handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs);
1292724d91d778e71c8186399f4955de14b54812b3edAravind Akella
12934949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    status_t err = sensor->batch(connection.get(), handle, 0, samplingPeriodNs,
1294724d91d778e71c8186399f4955de14b54812b3edAravind Akella                                 maxBatchReportLatencyNs);
12956c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
129620483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu    // Call flush() before calling activate() on the sensor. Wait for a first
129720483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu    // flush complete event before sending events on this connection. Ignore
129820483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu    // one-shot sensors which don't support flush(). Ignore on-change sensors
129920483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu    // to maintain the on-change logic (any on-change events except the initial
130020483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu    // one should be trigger by a change in value). Also if this sensor isn't
130120483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu    // already active, don't call flush().
130220483c49377fdb0330d9dfbbb2168b470c0b29d3Peng Xu    if (err == NO_ERROR &&
13032576cb63b3fe1592f54816625036566b9eb0793aPeng Xu            sensor->getSensor().getReportingMode() == AREPORTING_MODE_CONTINUOUS &&
13045466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            rec->getNumConnections() > 1) {
13055466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella        connection->setFirstFlushPending(handle, true);
13064c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        status_t err_flush = sensor->flush(connection.get(), handle);
13075466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella        // Flush may return error if the underlying h/w sensor uses an older HAL.
13086c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        if (err_flush == NO_ERROR) {
13096c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            rec->addPendingFlushConnection(connection.get());
13105466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella        } else {
13115466c3d20d03d4ae4b0fd0e0a93175091e3b0bb2Aravind Akella            connection->setFirstFlushPending(handle, false);
13124c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella        }
13134c8b951f8d6a121e758bd3905fa8987c77863790Aravind Akella    }
1314724d91d778e71c8186399f4955de14b54812b3edAravind Akella
1315724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (err == NO_ERROR) {
1316724d91d778e71c8186399f4955de14b54812b3edAravind Akella        ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle);
1317724d91d778e71c8186399f4955de14b54812b3edAravind Akella        err = sensor->activate(connection.get(), true);
1318724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
1319724d91d778e71c8186399f4955de14b54812b3edAravind Akella
13208a96955c8e14db40b16164236830fc9506a00872Aravind Akella    if (err == NO_ERROR) {
13218a96955c8e14db40b16164236830fc9506a00872Aravind Akella        connection->updateLooperRegistration(mLooper);
132251224681c9a80ff714d40c26d8f465fb1bae17e2Peng Xu
132351224681c9a80ff714d40c26d8f465fb1bae17e2Peng Xu        mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex) =
132451224681c9a80ff714d40c26d8f465fb1bae17e2Peng Xu                SensorRegistrationInfo(handle, connection->getPackageName(),
132551224681c9a80ff714d40c26d8f465fb1bae17e2Peng Xu                                       samplingPeriodNs, maxBatchReportLatencyNs, true);
132618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        mNextSensorRegIndex = (mNextSensorRegIndex + 1) % SENSOR_REGISTRATIONS_BUF_SIZE;
132756ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella    }
132856ae42613c91f6a6fb0dc3f626daa24666fd18c2Aravind Akella
13294342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (err != NO_ERROR) {
1330724d91d778e71c8186399f4955de14b54812b3edAravind Akella        // batch/activate has failed, reset our state.
1331ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        cleanupWithoutDisableLocked(connection, handle);
13324342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
1333fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    return err;
1334fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1335fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
133647e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xustatus_t SensorService::disable(const sp<SensorEventConnection>& connection, int handle) {
133750df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian    if (mInitCheck != NO_ERROR)
133850df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian        return mInitCheck;
133950df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
1340ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    Mutex::Autolock _l(mLock);
1341ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    status_t err = cleanupWithoutDisableLocked(connection, handle);
13424342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (err == NO_ERROR) {
1343755c451c7861a029e26e5f16e319b629169e656dPeng Xu        sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
1344755c451c7861a029e26e5f16e319b629169e656dPeng Xu        err = sensor != nullptr ? sensor->activate(connection.get(), false) : status_t(BAD_VALUE);
134518d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella
134618d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    }
134718d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella    if (err == NO_ERROR) {
134851224681c9a80ff714d40c26d8f465fb1bae17e2Peng Xu        mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex) =
134951224681c9a80ff714d40c26d8f465fb1bae17e2Peng Xu                SensorRegistrationInfo(handle, connection->getPackageName(), 0, 0, false);
135018d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella        mNextSensorRegIndex = (mNextSensorRegIndex + 1) % SENSOR_REGISTRATIONS_BUF_SIZE;
13514342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    }
13524342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    return err;
13534342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh}
13544342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
1355ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisable(
1356ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        const sp<SensorEventConnection>& connection, int handle) {
1357fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    Mutex::Autolock _l(mLock);
1358ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    return cleanupWithoutDisableLocked(connection, handle);
1359ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian}
1360ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian
1361ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianstatus_t SensorService::cleanupWithoutDisableLocked(
1362ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian        const sp<SensorEventConnection>& connection, int handle) {
1363fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    SensorRecord* rec = mActiveSensors.valueFor(handle);
1364fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian    if (rec) {
1365fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        // see if this connection becomes inactive
1366787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian        if (connection->removeSensor(handle)) {
1367787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian            BatteryService::disableSensor(connection->getUid(), handle);
1368787ac1b388f144f5e6dd38f8b807866a5256dafcMathias Agopian        }
1369fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        if (connection->hasAnySensor() == false) {
13708a96955c8e14db40b16164236830fc9506a00872Aravind Akella            connection->updateLooperRegistration(mLooper);
1371fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            mActiveConnections.remove(connection);
1372fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
1373fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        // see if this sensor becomes inactive
1374fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        if (rec->removeConnection(connection)) {
1375fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            mActiveSensors.removeItem(handle);
1376755c451c7861a029e26e5f16e319b629169e656dPeng Xu            mActiveVirtualSensors.erase(handle);
1377fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian            delete rec;
1378fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian        }
13794342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh        return NO_ERROR;
13807c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopian    }
13814342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    return BAD_VALUE;
1382fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1383fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
13847c1c531872a95051cb11ec829e3daf890d9bb58aMathias Agopianstatus_t SensorService::setEventRate(const sp<SensorEventConnection>& connection,
138547e96014fe6576a0ae7b02e7a2cb2275e549bbc9Peng Xu        int handle, nsecs_t ns, const String16& opPackageName) {
138650df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian    if (mInitCheck != NO_ERROR)
138750df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian        return mInitCheck;
138850df2959e58fc7408f98d11d77c8428397dca445Mathias Agopian
1389755c451c7861a029e26e5f16e319b629169e656dPeng Xu    sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
1390755c451c7861a029e26e5f16e319b629169e656dPeng Xu    if (sensor == nullptr ||
1391755c451c7861a029e26e5f16e319b629169e656dPeng Xu        !canAccessSensor(sensor->getSensor(), "Tried configuring", opPackageName)) {
1392700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return BAD_VALUE;
1393700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
1394700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
13951cd700015318727d6d42236ab6274f1949fb08baMathias Agopian    if (ns < 0)
13961cd700015318727d6d42236ab6274f1949fb08baMathias Agopian        return BAD_VALUE;
13971cd700015318727d6d42236ab6274f1949fb08baMathias Agopian
139862569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian    nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
139962569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian    if (ns < minDelayNs) {
140062569ecf526c7c01cb68ea461c6bbd3cb26057d2Mathias Agopian        ns = minDelayNs;
1401ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian    }
1402ae09d65f5b35cb51da2e1386a6dd7a52085f1325Mathias Agopian
1403f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    return sensor->setDelay(connection.get(), handle, ns);
1404fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}
1405fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian
1406b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslavstatus_t SensorService::flushSensor(const sp<SensorEventConnection>& connection,
1407b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        const String16& opPackageName) {
1408700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    if (mInitCheck != NO_ERROR) return mInitCheck;
14099e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    SensorDevice& dev(SensorDevice::getInstance());
14109e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    const int halVersion = dev.getHalDeviceVersion();
14119e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    status_t err(NO_ERROR);
14129e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    Mutex::Autolock _l(mLock);
14139e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    // Loop through all sensors for this connection and call flush on each of them.
14149e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    for (size_t i = 0; i < connection->mSensorInfo.size(); ++i) {
14159e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        const int handle = connection->mSensorInfo.keyAt(i);
1416755c451c7861a029e26e5f16e319b629169e656dPeng Xu        sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
1417755c451c7861a029e26e5f16e319b629169e656dPeng Xu        if (sensor == nullptr) {
1418755c451c7861a029e26e5f16e319b629169e656dPeng Xu            continue;
1419755c451c7861a029e26e5f16e319b629169e656dPeng Xu        }
14209e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
14219e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            ALOGE("flush called on a one-shot sensor");
14229e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            err = INVALID_OPERATION;
14239e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            continue;
14249e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        }
14258493b79e1cff92450076ca7450c4bf4e434a6816Aravind Akella        if (halVersion <= SENSORS_DEVICE_API_VERSION_1_0 || isVirtualSensor(handle)) {
14269e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            // For older devices just increment pending flush count which will send a trivial
14279e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            // flush complete event.
14288a96955c8e14db40b16164236830fc9506a00872Aravind Akella            connection->incrementPendingFlushCount(handle);
14299e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        } else {
1430b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            if (!canAccessSensor(sensor->getSensor(), "Tried flushing", opPackageName)) {
1431b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                err = INVALID_OPERATION;
1432b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                continue;
1433b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            }
14349e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            status_t err_flush = sensor->flush(connection.get(), handle);
14359e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            if (err_flush == NO_ERROR) {
14369e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella                SensorRecord* rec = mActiveSensors.valueFor(handle);
14379e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella                if (rec != NULL) rec->addPendingFlushConnection(connection);
14389e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            }
14399e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella            err = (err_flush != NO_ERROR) ? err_flush : err;
14409e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella        }
14416c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    }
14429e3adfcebf28c5c76085108dffe98c74df56857dAravind Akella    return err;
1443700180487ffec09d9df1657b018a7caadac24b75Aravind Akella}
1444700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
1445b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslavbool SensorService::canAccessSensor(const Sensor& sensor, const char* operation,
1446b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        const String16& opPackageName) {
1447b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    const String8& requiredPermission = sensor.getRequiredPermission();
1448700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
1449b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (requiredPermission.length() <= 0) {
1450700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return true;
1451b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    }
1452b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav
1453b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    bool hasPermission = false;
1454b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav
1455b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    // Runtime permissions can't use the cache as they may change.
1456b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (sensor.isRequiredPermissionRuntime()) {
1457b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        hasPermission = checkPermission(String16(requiredPermission),
1458b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                IPCThreadState::self()->getCallingPid(), IPCThreadState::self()->getCallingUid());
1459700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    } else {
1460b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        hasPermission = PermissionCache::checkCallingPermission(String16(requiredPermission));
1461b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    }
1462b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav
1463b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (!hasPermission) {
1464b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        ALOGE("%s a sensor (%s) without holding its required permission: %s",
1465b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                operation, sensor.getName().string(), sensor.getRequiredPermission().string());
1466700180487ffec09d9df1657b018a7caadac24b75Aravind Akella        return false;
1467700180487ffec09d9df1657b018a7caadac24b75Aravind Akella    }
1468b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav
1469b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    const int32_t opCode = sensor.getRequiredAppOp();
1470b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    if (opCode >= 0) {
1471b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        AppOpsManager appOps;
1472b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        if (appOps.noteOp(opCode, IPCThreadState::self()->getCallingUid(), opPackageName)
1473b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                        != AppOpsManager::MODE_ALLOWED) {
1474d4036b6b7f9609fe09efabdbfbb8c8f9428f76f7Andreas Gampe            ALOGE("%s a sensor (%s) without enabled required app op: %d",
1475b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav                    operation, sensor.getName().string(), opCode);
1476b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav            return false;
1477b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav        }
1478b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    }
1479b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav
1480b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav    return true;
1481700180487ffec09d9df1657b018a7caadac24b75Aravind Akella}
1482700180487ffec09d9df1657b018a7caadac24b75Aravind Akella
14839a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockState() {
14849a844cf78f09953145200b4074d47589257a408cAravind Akella    Mutex::Autolock _l(mLock);
14859a844cf78f09953145200b4074d47589257a408cAravind Akella    checkWakeLockStateLocked();
14869a844cf78f09953145200b4074d47589257a408cAravind Akella}
14879a844cf78f09953145200b4074d47589257a408cAravind Akella
14889a844cf78f09953145200b4074d47589257a408cAravind Akellavoid SensorService::checkWakeLockStateLocked() {
14899a844cf78f09953145200b4074d47589257a408cAravind Akella    if (!mWakeLockAcquired) {
14909a844cf78f09953145200b4074d47589257a408cAravind Akella        return;
14919a844cf78f09953145200b4074d47589257a408cAravind Akella    }
14929a844cf78f09953145200b4074d47589257a408cAravind Akella    bool releaseLock = true;
14939a844cf78f09953145200b4074d47589257a408cAravind Akella    for (size_t i=0 ; i<mActiveConnections.size() ; i++) {
14949a844cf78f09953145200b4074d47589257a408cAravind Akella        sp<SensorEventConnection> connection(mActiveConnections[i].promote());
14959a844cf78f09953145200b4074d47589257a408cAravind Akella        if (connection != 0) {
14969a844cf78f09953145200b4074d47589257a408cAravind Akella            if (connection->needsWakeLock()) {
14979a844cf78f09953145200b4074d47589257a408cAravind Akella                releaseLock = false;
14989a844cf78f09953145200b4074d47589257a408cAravind Akella                break;
14999a844cf78f09953145200b4074d47589257a408cAravind Akella            }
15009a844cf78f09953145200b4074d47589257a408cAravind Akella        }
15019a844cf78f09953145200b4074d47589257a408cAravind Akella    }
15029a844cf78f09953145200b4074d47589257a408cAravind Akella    if (releaseLock) {
1503b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        setWakeLockAcquiredLocked(false);
1504b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    }
1505b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
1506b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
1507b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::sendEventsFromCache(const sp<SensorEventConnection>& connection) {
1508b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    Mutex::Autolock _l(mLock);
1509b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    connection->writeToSocketFromCache();
1510b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    if (connection->needsWakeLock()) {
1511b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        setWakeLockAcquiredLocked(true);
1512b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    }
1513b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella}
1514b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella
1515b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akellavoid SensorService::populateActiveConnections(
1516b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        SortedVector< sp<SensorEventConnection> >* activeConnections) {
1517b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    Mutex::Autolock _l(mLock);
1518b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella    for (size_t i=0 ; i < mActiveConnections.size(); ++i) {
1519b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        sp<SensorEventConnection> connection(mActiveConnections[i].promote());
1520b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        if (connection != 0) {
1521b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella            activeConnections->add(connection);
1522b4373ac9f53e3a6edee915715101d535e1a851a1Aravind Akella        }
15239a844cf78f09953145200b4074d47589257a408cAravind Akella    }
15249a844cf78f09953145200b4074d47589257a408cAravind Akella}
15256c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
15264949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akellabool SensorService::isWhiteListedPackage(const String8& packageName) {
1527841a5926fc9b3f9f0e654ba3aab8e43bea7de7f1Aravind Akella    return (packageName.contains(mWhiteListedPackage.string()));
15284949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella}
15294949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
1530e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xubool SensorService::isOperationRestricted(const String16& opPackageName) {
1531e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    Mutex::Autolock _l(mLock);
1532e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    if (mCurrentOperatingMode != RESTRICTED) {
1533e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        String8 package(opPackageName);
1534e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu        return !isWhiteListedPackage(package);
1535e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    }
1536e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    return false;
1537e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu}
1538e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu
1539fc32881fcc68640d008c7515cdd1bcd866f72cd5Mathias Agopian}; // namespace android
1540