1f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian/*
2f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian * Copyright (C) 2010 The Android Open Source Project
3f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian *
4f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License");
5f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian * you may not use this file except in compliance with the License.
6f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian * You may obtain a copy of the License at
7f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian *
8f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian *      http://www.apache.org/licenses/LICENSE-2.0
9f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian *
10f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian * Unless required by applicable law or agreed to in writing, software
11f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS,
12f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian * See the License for the specific language governing permissions and
14f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian * limitations under the License.
15f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian */
16f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
17db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn#include <inttypes.h>
18f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include <math.h>
19db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn#include <stdint.h>
20f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include <sys/types.h>
21f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
22f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include <utils/Atomic.h>
23f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include <utils/Errors.h>
24f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include <utils/Singleton.h>
25f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
26f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include <binder/BinderService.h>
27f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include <binder/Parcel.h>
28f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include <binder/IServiceManager.h>
29f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
30f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include <hardware/sensors.h>
31f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
32f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include "SensorDevice.h"
33a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian#include "SensorService.h"
34f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
35f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopiannamespace android {
36f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian// ---------------------------------------------------------------------------
37f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
38f001c92436b4a66eb7687286325ced7f10c9f917Mathias AgopianANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice)
39f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
40f001c92436b4a66eb7687286325ced7f10c9f917Mathias AgopianSensorDevice::SensorDevice()
41f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    :  mSensorDevice(0),
42f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian       mSensorModule(0)
43f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{
44f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
45f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            (hw_module_t const**)&mSensorModule);
46f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
47f5a1230d322c14c42331d0a1536b50c87742973bSteve Block    ALOGE_IF(err, "couldn't load %s module (%s)",
48f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            SENSORS_HARDWARE_MODULE_ID, strerror(-err));
49f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
50f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    if (mSensorModule) {
51724d91d778e71c8186399f4955de14b54812b3edAravind Akella        err = sensors_open_1(&mSensorModule->common, &mSensorDevice);
52f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
53f5a1230d322c14c42331d0a1536b50c87742973bSteve Block        ALOGE_IF(err, "couldn't open device for module %s (%s)",
54f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                SENSORS_HARDWARE_MODULE_ID, strerror(-err));
55f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
56f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        if (mSensorDevice) {
576c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            if (mSensorDevice->common.version == SENSORS_DEVICE_API_VERSION_1_1 ||
586c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                mSensorDevice->common.version == SENSORS_DEVICE_API_VERSION_1_2) {
596c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella                ALOGE(">>>> WARNING <<< Upgrade sensor HAL to version 1_3");
606c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella            }
616c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella
62f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            sensor_t const* list;
63f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
64f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            mActivationCount.setCapacity(count);
65f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            Info model;
66f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            for (size_t i=0 ; i<size_t(count) ; i++) {
67f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian                mActivationCount.add(list[i].handle, model);
68724d91d778e71c8186399f4955de14b54812b3edAravind Akella                mSensorDevice->activate(
69724d91d778e71c8186399f4955de14b54812b3edAravind Akella                        reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
70724d91d778e71c8186399f4955de14b54812b3edAravind Akella                        list[i].handle, 0);
71f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian            }
72f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        }
73f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    }
74f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
75f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
76ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopianvoid SensorDevice::dump(String8& result)
77f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{
78f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    if (!mSensorModule) return;
79f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    sensor_t const* list;
80f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
81f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
82444f2675728dde36378beb8e67a94f86ebf1ca46Aravind Akella    result.appendFormat("halVersion 0x%08x\n", getHalDeviceVersion());
83ba02cd2f6cc3f59adf66cb2b9176bfe6c9e382d1Mathias Agopian    result.appendFormat("%d h/w sensors:\n", int(count));
84f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
85f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    Mutex::Autolock _l(mLock);
86f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    for (size_t i=0 ; i<size_t(count) ; i++) {
87667102f6b072582fe497599e0b760f9fc94ceffaMathias Agopian        const Info& info = mActivationCount.valueFor(list[i].handle);
884949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        if (info.batchParams.isEmpty()) continue;
8992dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn        result.appendFormat("handle=0x%08x, active-count=%zu, batch_period(ms)={ ", list[i].handle,
90724d91d778e71c8186399f4955de14b54812b3edAravind Akella                            info.batchParams.size());
91724d91d778e71c8186399f4955de14b54812b3edAravind Akella        for (size_t j = 0; j < info.batchParams.size(); j++) {
9218d6d51a00897988e3347b130f533e9ffdd8c365Aravind Akella            const BatchParams& params = info.batchParams.valueAt(j);
93724d91d778e71c8186399f4955de14b54812b3edAravind Akella            result.appendFormat("%4.1f%s", params.batchDelay / 1e6f,
94724d91d778e71c8186399f4955de14b54812b3edAravind Akella                                j < info.batchParams.size() - 1 ? ", " : "");
95667102f6b072582fe497599e0b760f9fc94ceffaMathias Agopian        }
96724d91d778e71c8186399f4955de14b54812b3edAravind Akella        result.appendFormat(" }, selected=%4.1f ms\n", info.bestBatchParams.batchDelay / 1e6f);
97724d91d778e71c8186399f4955de14b54812b3edAravind Akella
9892dc3fc52cf097bd105460cf377779bdcf146d62Mark Salyzyn        result.appendFormat("handle=0x%08x, active-count=%zu, batch_timeout(ms)={ ", list[i].handle,
99724d91d778e71c8186399f4955de14b54812b3edAravind Akella                            info.batchParams.size());
100724d91d778e71c8186399f4955de14b54812b3edAravind Akella        for (size_t j = 0; j < info.batchParams.size(); j++) {
101724d91d778e71c8186399f4955de14b54812b3edAravind Akella            BatchParams params = info.batchParams.valueAt(j);
102724d91d778e71c8186399f4955de14b54812b3edAravind Akella            result.appendFormat("%4.1f%s", params.batchTimeout / 1e6f,
103724d91d778e71c8186399f4955de14b54812b3edAravind Akella                                j < info.batchParams.size() - 1 ? ", " : "");
104724d91d778e71c8186399f4955de14b54812b3edAravind Akella        }
105724d91d778e71c8186399f4955de14b54812b3edAravind Akella        result.appendFormat(" }, selected=%4.1f ms\n", info.bestBatchParams.batchTimeout / 1e6f);
106f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    }
107f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
108f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
109f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopianssize_t SensorDevice::getSensorList(sensor_t const** list) {
110f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    if (!mSensorModule) return NO_INIT;
111f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    ssize_t count = mSensorModule->get_sensors_list(mSensorModule, list);
112f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    return count;
113f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
114f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
115f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopianstatus_t SensorDevice::initCheck() const {
116f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    return mSensorDevice && mSensorModule ? NO_ERROR : NO_INIT;
117f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
118f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
119f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopianssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
120f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    if (!mSensorDevice) return NO_INIT;
1211a62301fc58cd2af18239b0415813461bf5fc41bMathias Agopian    ssize_t c;
1221a62301fc58cd2af18239b0415813461bf5fc41bMathias Agopian    do {
123724d91d778e71c8186399f4955de14b54812b3edAravind Akella        c = mSensorDevice->poll(reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice),
124724d91d778e71c8186399f4955de14b54812b3edAravind Akella                                buffer, count);
1251a62301fc58cd2af18239b0415813461bf5fc41bMathias Agopian    } while (c == -EINTR);
1261a62301fc58cd2af18239b0415813461bf5fc41bMathias Agopian    return c;
127f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
128f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
129ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianvoid SensorDevice::autoDisable(void *ident, int handle) {
130ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    Info& info( mActivationCount.editValueFor(handle) );
1314c01b1ad80e084f0cd1057f89fdd1fcedf19dd96Jaikumar Ganesh    Mutex::Autolock _l(mLock);
132724d91d778e71c8186399f4955de14b54812b3edAravind Akella    info.removeBatchParamsForIdent(ident);
1334c01b1ad80e084f0cd1057f89fdd1fcedf19dd96Jaikumar Ganesh}
1344c01b1ad80e084f0cd1057f89fdd1fcedf19dd96Jaikumar Ganesh
135f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopianstatus_t SensorDevice::activate(void* ident, int handle, int enabled)
136f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{
137f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    if (!mSensorDevice) return NO_INIT;
138f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    status_t err(NO_ERROR);
139f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    bool actuateHardware = false;
140f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
141724d91d778e71c8186399f4955de14b54812b3edAravind Akella    Mutex::Autolock _l(mLock);
142f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    Info& info( mActivationCount.editValueFor(handle) );
143a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian
144a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block    ALOGD_IF(DEBUG_CONNECTIONS,
145db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn             "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%zu",
146724d91d778e71c8186399f4955de14b54812b3edAravind Akella             ident, handle, enabled, info.batchParams.size());
147a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian
148f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    if (enabled) {
149db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn        ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%zd", info.batchParams.indexOfKey(ident));
150a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian
1514949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        if (isClientDisabledLocked(ident)) {
1524949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            return INVALID_OPERATION;
1534949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        }
1544949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
155724d91d778e71c8186399f4955de14b54812b3edAravind Akella        if (info.batchParams.indexOfKey(ident) >= 0) {
1564949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella          if (info.numActiveClients() == 1) {
157724d91d778e71c8186399f4955de14b54812b3edAravind Akella              // This is the first connection, we need to activate the underlying h/w sensor.
158724d91d778e71c8186399f4955de14b54812b3edAravind Akella              actuateHardware = true;
159724d91d778e71c8186399f4955de14b54812b3edAravind Akella          }
16050b66767f6c5635430483393e17d15969dfe2f05Mathias Agopian        } else {
161724d91d778e71c8186399f4955de14b54812b3edAravind Akella            // Log error. Every activate call should be preceded by a batch() call.
162724d91d778e71c8186399f4955de14b54812b3edAravind Akella            ALOGE("\t >>>ERROR: activate called without batch");
163f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        }
16450b66767f6c5635430483393e17d15969dfe2f05Mathias Agopian    } else {
165db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn        ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident));
166a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian
167724d91d778e71c8186399f4955de14b54812b3edAravind Akella        if (info.removeBatchParamsForIdent(ident) >= 0) {
1684949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            if (info.numActiveClients() == 0) {
169724d91d778e71c8186399f4955de14b54812b3edAravind Akella                // This is the last connection, we need to de-activate the underlying h/w sensor.
17050b66767f6c5635430483393e17d15969dfe2f05Mathias Agopian                actuateHardware = true;
171724d91d778e71c8186399f4955de14b54812b3edAravind Akella            } else {
172724d91d778e71c8186399f4955de14b54812b3edAravind Akella                const int halVersion = getHalDeviceVersion();
173724d91d778e71c8186399f4955de14b54812b3edAravind Akella                if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) {
174724d91d778e71c8186399f4955de14b54812b3edAravind Akella                    // Call batch for this sensor with the previously calculated best effort
175724d91d778e71c8186399f4955de14b54812b3edAravind Akella                    // batch_rate and timeout. One of the apps has unregistered for sensor
176724d91d778e71c8186399f4955de14b54812b3edAravind Akella                    // events, and the best effort batch parameters might have changed.
177724d91d778e71c8186399f4955de14b54812b3edAravind Akella                    ALOGD_IF(DEBUG_CONNECTIONS,
178db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn                             "\t>>> actuating h/w batch %d %d %" PRId64 " %" PRId64, handle,
179724d91d778e71c8186399f4955de14b54812b3edAravind Akella                             info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
180724d91d778e71c8186399f4955de14b54812b3edAravind Akella                             info.bestBatchParams.batchTimeout);
181724d91d778e71c8186399f4955de14b54812b3edAravind Akella                    mSensorDevice->batch(mSensorDevice, handle,info.bestBatchParams.flags,
182724d91d778e71c8186399f4955de14b54812b3edAravind Akella                                         info.bestBatchParams.batchDelay,
183724d91d778e71c8186399f4955de14b54812b3edAravind Akella                                         info.bestBatchParams.batchTimeout);
184724d91d778e71c8186399f4955de14b54812b3edAravind Akella                }
18550b66767f6c5635430483393e17d15969dfe2f05Mathias Agopian            }
18650b66767f6c5635430483393e17d15969dfe2f05Mathias Agopian        } else {
18750b66767f6c5635430483393e17d15969dfe2f05Mathias Agopian            // sensor wasn't enabled for this ident
18850b66767f6c5635430483393e17d15969dfe2f05Mathias Agopian        }
1894949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
1904949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        if (isClientDisabledLocked(ident)) {
1914949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            return NO_ERROR;
1924949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        }
193f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    }
19450b66767f6c5635430483393e17d15969dfe2f05Mathias Agopian
195f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    if (actuateHardware) {
1964949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
1974949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella                 enabled);
198724d91d778e71c8186399f4955de14b54812b3edAravind Akella        err = mSensorDevice->activate(
199724d91d778e71c8186399f4955de14b54812b3edAravind Akella                reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), handle, enabled);
200724d91d778e71c8186399f4955de14b54812b3edAravind Akella        ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
201724d91d778e71c8186399f4955de14b54812b3edAravind Akella                 strerror(-err));
202724d91d778e71c8186399f4955de14b54812b3edAravind Akella
203724d91d778e71c8186399f4955de14b54812b3edAravind Akella        if (err != NO_ERROR && enabled) {
204724d91d778e71c8186399f4955de14b54812b3edAravind Akella            // Failure when enabling the sensor. Clean up on failure.
205724d91d778e71c8186399f4955de14b54812b3edAravind Akella            info.removeBatchParamsForIdent(ident);
206724d91d778e71c8186399f4955de14b54812b3edAravind Akella        }
207724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
208a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian
209724d91d778e71c8186399f4955de14b54812b3edAravind Akella    // On older devices which do not support batch, call setDelay().
2104949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1 && info.numActiveClients() > 0) {
211db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn        ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w setDelay %d %" PRId64, handle,
212724d91d778e71c8186399f4955de14b54812b3edAravind Akella                 info.bestBatchParams.batchDelay);
213724d91d778e71c8186399f4955de14b54812b3edAravind Akella        mSensorDevice->setDelay(
214724d91d778e71c8186399f4955de14b54812b3edAravind Akella                reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
215724d91d778e71c8186399f4955de14b54812b3edAravind Akella                handle, info.bestBatchParams.batchDelay);
216724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
217724d91d778e71c8186399f4955de14b54812b3edAravind Akella    return err;
218724d91d778e71c8186399f4955de14b54812b3edAravind Akella}
219ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian
220724d91d778e71c8186399f4955de14b54812b3edAravind Akellastatus_t SensorDevice::batch(void* ident, int handle, int flags, int64_t samplingPeriodNs,
221724d91d778e71c8186399f4955de14b54812b3edAravind Akella                             int64_t maxBatchReportLatencyNs) {
222724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (!mSensorDevice) return NO_INIT;
223724d91d778e71c8186399f4955de14b54812b3edAravind Akella
224724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
225724d91d778e71c8186399f4955de14b54812b3edAravind Akella        samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
226724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
227724d91d778e71c8186399f4955de14b54812b3edAravind Akella
228724d91d778e71c8186399f4955de14b54812b3edAravind Akella    const int halVersion = getHalDeviceVersion();
2296c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella    if (halVersion < SENSORS_DEVICE_API_VERSION_1_1 && maxBatchReportLatencyNs != 0) {
2306c2664ae34fd582bc174d3c83e2b18e895ca2496Aravind Akella        // Batch is not supported on older devices return invalid operation.
231724d91d778e71c8186399f4955de14b54812b3edAravind Akella        return INVALID_OPERATION;
232f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    }
233f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
234724d91d778e71c8186399f4955de14b54812b3edAravind Akella    ALOGD_IF(DEBUG_CONNECTIONS,
235db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn             "SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%" PRId64 " timeout=%" PRId64,
236724d91d778e71c8186399f4955de14b54812b3edAravind Akella             ident, handle, flags, samplingPeriodNs, maxBatchReportLatencyNs);
237724d91d778e71c8186399f4955de14b54812b3edAravind Akella
238724d91d778e71c8186399f4955de14b54812b3edAravind Akella    Mutex::Autolock _l(mLock);
239724d91d778e71c8186399f4955de14b54812b3edAravind Akella    Info& info(mActivationCount.editValueFor(handle));
240724d91d778e71c8186399f4955de14b54812b3edAravind Akella
241724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (info.batchParams.indexOfKey(ident) < 0) {
242724d91d778e71c8186399f4955de14b54812b3edAravind Akella        BatchParams params(flags, samplingPeriodNs, maxBatchReportLatencyNs);
243724d91d778e71c8186399f4955de14b54812b3edAravind Akella        info.batchParams.add(ident, params);
244724d91d778e71c8186399f4955de14b54812b3edAravind Akella    } else {
245724d91d778e71c8186399f4955de14b54812b3edAravind Akella        // A batch has already been called with this ident. Update the batch parameters.
246724d91d778e71c8186399f4955de14b54812b3edAravind Akella        info.setBatchParamsForIdent(ident, flags, samplingPeriodNs, maxBatchReportLatencyNs);
247f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    }
248f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
249724d91d778e71c8186399f4955de14b54812b3edAravind Akella    BatchParams prevBestBatchParams = info.bestBatchParams;
250724d91d778e71c8186399f4955de14b54812b3edAravind Akella    // Find the minimum of all timeouts and batch_rates for this sensor.
251724d91d778e71c8186399f4955de14b54812b3edAravind Akella    info.selectBatchParams();
252724d91d778e71c8186399f4955de14b54812b3edAravind Akella
253724d91d778e71c8186399f4955de14b54812b3edAravind Akella    ALOGD_IF(DEBUG_CONNECTIONS,
254db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn             "\t>>> curr_period=%" PRId64 " min_period=%" PRId64
255db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn             " curr_timeout=%" PRId64 " min_timeout=%" PRId64,
256724d91d778e71c8186399f4955de14b54812b3edAravind Akella             prevBestBatchParams.batchDelay, info.bestBatchParams.batchDelay,
257724d91d778e71c8186399f4955de14b54812b3edAravind Akella             prevBestBatchParams.batchTimeout, info.bestBatchParams.batchTimeout);
258724d91d778e71c8186399f4955de14b54812b3edAravind Akella
259724d91d778e71c8186399f4955de14b54812b3edAravind Akella    status_t err(NO_ERROR);
260724d91d778e71c8186399f4955de14b54812b3edAravind Akella    // If the min period or min timeout has changed since the last batch call, call batch.
261724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (prevBestBatchParams != info.bestBatchParams) {
262724d91d778e71c8186399f4955de14b54812b3edAravind Akella        if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) {
263db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn            ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH %d %d %" PRId64 " %" PRId64, handle,
264724d91d778e71c8186399f4955de14b54812b3edAravind Akella                     info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
265724d91d778e71c8186399f4955de14b54812b3edAravind Akella                     info.bestBatchParams.batchTimeout);
266724d91d778e71c8186399f4955de14b54812b3edAravind Akella            err = mSensorDevice->batch(mSensorDevice, handle, info.bestBatchParams.flags,
267724d91d778e71c8186399f4955de14b54812b3edAravind Akella                                       info.bestBatchParams.batchDelay,
268724d91d778e71c8186399f4955de14b54812b3edAravind Akella                                       info.bestBatchParams.batchTimeout);
269724d91d778e71c8186399f4955de14b54812b3edAravind Akella        } else {
270724d91d778e71c8186399f4955de14b54812b3edAravind Akella            // For older devices which do not support batch, call setDelay() after activate() is
271724d91d778e71c8186399f4955de14b54812b3edAravind Akella            // called. Some older devices may not support calling setDelay before activate(), so
272724d91d778e71c8186399f4955de14b54812b3edAravind Akella            // call setDelay in SensorDevice::activate() method.
273724d91d778e71c8186399f4955de14b54812b3edAravind Akella        }
274724d91d778e71c8186399f4955de14b54812b3edAravind Akella        if (err != NO_ERROR) {
275db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn            ALOGE("sensor batch failed %p %d %d %" PRId64 " %" PRId64 " err=%s",
276db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn                  mSensorDevice, handle,
277724d91d778e71c8186399f4955de14b54812b3edAravind Akella                  info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
278724d91d778e71c8186399f4955de14b54812b3edAravind Akella                  info.bestBatchParams.batchTimeout, strerror(-err));
279724d91d778e71c8186399f4955de14b54812b3edAravind Akella            info.removeBatchParamsForIdent(ident);
280724d91d778e71c8186399f4955de14b54812b3edAravind Akella        }
281724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
282f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    return err;
283f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
284f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
285724d91d778e71c8186399f4955de14b54812b3edAravind Akellastatus_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs)
286f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian{
287f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    if (!mSensorDevice) return NO_INIT;
288724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
289724d91d778e71c8186399f4955de14b54812b3edAravind Akella        samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
290724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
291667102f6b072582fe497599e0b760f9fc94ceffaMathias Agopian    Mutex::Autolock _l(mLock);
2924949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    if (isClientDisabledLocked(ident)) return INVALID_OPERATION;
293f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    Info& info( mActivationCount.editValueFor(handle) );
294724d91d778e71c8186399f4955de14b54812b3edAravind Akella    // If the underlying sensor is NOT in continuous mode, setDelay() should return an error.
295724d91d778e71c8186399f4955de14b54812b3edAravind Akella    // Calling setDelay() in batch mode is an invalid operation.
296724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (info.bestBatchParams.batchTimeout != 0) {
297724d91d778e71c8186399f4955de14b54812b3edAravind Akella      return INVALID_OPERATION;
298724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
299724d91d778e71c8186399f4955de14b54812b3edAravind Akella    ssize_t index = info.batchParams.indexOfKey(ident);
300724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (index < 0) {
301724d91d778e71c8186399f4955de14b54812b3edAravind Akella        return BAD_INDEX;
302724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
303724d91d778e71c8186399f4955de14b54812b3edAravind Akella    BatchParams& params = info.batchParams.editValueAt(index);
304724d91d778e71c8186399f4955de14b54812b3edAravind Akella    params.batchDelay = samplingPeriodNs;
305724d91d778e71c8186399f4955de14b54812b3edAravind Akella    info.selectBatchParams();
306724d91d778e71c8186399f4955de14b54812b3edAravind Akella    return mSensorDevice->setDelay(reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
307724d91d778e71c8186399f4955de14b54812b3edAravind Akella                                   handle, info.bestBatchParams.batchDelay);
308667102f6b072582fe497599e0b760f9fc94ceffaMathias Agopian}
309984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian
3104342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganeshint SensorDevice::getHalDeviceVersion() const {
3114342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    if (!mSensorDevice) return -1;
3124342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh    return mSensorDevice->common.version;
3134342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh}
3144342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
3159a844cf78f09953145200b4074d47589257a408cAravind Akellastatus_t SensorDevice::flush(void* ident, int handle) {
316724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1) {
317724d91d778e71c8186399f4955de14b54812b3edAravind Akella        return INVALID_OPERATION;
318724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
3194949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    if (isClientDisabled(ident)) return INVALID_OPERATION;
320724d91d778e71c8186399f4955de14b54812b3edAravind Akella    ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle);
321724d91d778e71c8186399f4955de14b54812b3edAravind Akella    return mSensorDevice->flush(mSensorDevice, handle);
322724d91d778e71c8186399f4955de14b54812b3edAravind Akella}
323724d91d778e71c8186399f4955de14b54812b3edAravind Akella
3244949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akellabool SensorDevice::isClientDisabled(void* ident) {
3254949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    Mutex::Autolock _l(mLock);
3264949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    return isClientDisabledLocked(ident);
3274949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella}
3284949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
3294949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akellabool SensorDevice::isClientDisabledLocked(void* ident) {
3304949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    return mDisabledClients.indexOf(ident) >= 0;
3314949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella}
3324949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
3334949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akellavoid SensorDevice::enableAllSensors() {
3344949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    Mutex::Autolock _l(mLock);
3354949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    mDisabledClients.clear();
3364949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    const int halVersion = getHalDeviceVersion();
3374949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    for (size_t i = 0; i< mActivationCount.size(); ++i) {
3384949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        Info& info = mActivationCount.editValueAt(i);
3394949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        if (info.batchParams.isEmpty()) continue;
3404949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        info.selectBatchParams();
3414949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        const int sensor_handle = mActivationCount.keyAt(i);
3424949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        ALOGD_IF(DEBUG_CONNECTIONS, "\t>> reenable actuating h/w sensor enable handle=%d ",
3434949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella                   sensor_handle);
3444949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        status_t err(NO_ERROR);
3454949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        if (halVersion > SENSORS_DEVICE_API_VERSION_1_0) {
3464949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            err = mSensorDevice->batch(mSensorDevice, sensor_handle,
3474949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella                 info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
3484949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella                 info.bestBatchParams.batchTimeout);
3494949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            ALOGE_IF(err, "Error calling batch on sensor %d (%s)", sensor_handle, strerror(-err));
3504949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        }
3514949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
3524949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        if (err == NO_ERROR) {
3534949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            err = mSensorDevice->activate(
3544949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella                    reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
3554949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella                    sensor_handle, 1);
3564949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            ALOGE_IF(err, "Error activating sensor %d (%s)", sensor_handle, strerror(-err));
3574949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        }
3584949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
3594949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        if (halVersion <= SENSORS_DEVICE_API_VERSION_1_0) {
3604949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella             err = mSensorDevice->setDelay(
3614949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella                    reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
3624949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella                    sensor_handle, info.bestBatchParams.batchDelay);
3634949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella             ALOGE_IF(err, "Error calling setDelay sensor %d (%s)", sensor_handle, strerror(-err));
3644949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        }
3654949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    }
3664949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella}
3674949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
3684949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akellavoid SensorDevice::disableAllSensors() {
3694949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    Mutex::Autolock _l(mLock);
370a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella   for (size_t i = 0; i< mActivationCount.size(); ++i) {
3714949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        const Info& info = mActivationCount.valueAt(i);
3724949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        // Check if this sensor has been activated previously and disable it.
3734949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        if (info.batchParams.size() > 0) {
3744949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella           const int sensor_handle = mActivationCount.keyAt(i);
3754949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella           ALOGD_IF(DEBUG_CONNECTIONS, "\t>> actuating h/w sensor disable handle=%d ",
3764949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella                   sensor_handle);
3774949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella           mSensorDevice->activate(
3784949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella                   reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice),
3794949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella                   sensor_handle, 0);
3804949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella           // Add all the connections that were registered for this sensor to the disabled
3814949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella           // clients list.
382b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav           for (size_t j = 0; j < info.batchParams.size(); ++j) {
3834949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella               mDisabledClients.add(info.batchParams.keyAt(j));
3844949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella           }
3854949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        }
3864949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    }
3874949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella}
3884949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
389b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslavstatus_t SensorDevice::injectSensorData(const sensors_event_t *injected_sensor_event) {
390a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella      ALOGD_IF(DEBUG_CONNECTIONS,
391a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella              "sensor_event handle=%d ts=%lld data=%.2f, %.2f, %.2f %.2f %.2f %.2f",
392a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               injected_sensor_event->sensor,
393a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               injected_sensor_event->timestamp, injected_sensor_event->data[0],
394a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               injected_sensor_event->data[1], injected_sensor_event->data[2],
395a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               injected_sensor_event->data[3], injected_sensor_event->data[4],
396a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella               injected_sensor_event->data[5]);
397a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella      if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4) {
398a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella          return INVALID_OPERATION;
399a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella      }
400a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella      return mSensorDevice->inject_sensor_data(mSensorDevice, injected_sensor_event);
401a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella}
402a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
403a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatus_t SensorDevice::setMode(uint32_t mode) {
404a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella     if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4) {
405a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella          return INVALID_OPERATION;
406a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella     }
407a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella     return mSensorModule->set_operation_mode(mode);
408a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella}
409a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
410667102f6b072582fe497599e0b760f9fc94ceffaMathias Agopian// ---------------------------------------------------------------------------
411984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian
4124949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akellaint SensorDevice::Info::numActiveClients() {
4134949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    SensorDevice& device(SensorDevice::getInstance());
4144949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    int num = 0;
4154949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    for (size_t i = 0; i < batchParams.size(); ++i) {
4164949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        if (!device.isClientDisabledLocked(batchParams.keyAt(i))) {
4174949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            ++num;
4184949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        }
4194949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    }
4204949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    return num;
4214949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella}
4224949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
423724d91d778e71c8186399f4955de14b54812b3edAravind Akellastatus_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int flags,
424724d91d778e71c8186399f4955de14b54812b3edAravind Akella                                                    int64_t samplingPeriodNs,
425724d91d778e71c8186399f4955de14b54812b3edAravind Akella                                                    int64_t maxBatchReportLatencyNs) {
426724d91d778e71c8186399f4955de14b54812b3edAravind Akella    ssize_t index = batchParams.indexOfKey(ident);
427667102f6b072582fe497599e0b760f9fc94ceffaMathias Agopian    if (index < 0) {
428db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn        ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%" PRId64 " timeout=%" PRId64 ") failed (%s)",
429724d91d778e71c8186399f4955de14b54812b3edAravind Akella              ident, samplingPeriodNs, maxBatchReportLatencyNs, strerror(-index));
430667102f6b072582fe497599e0b760f9fc94ceffaMathias Agopian        return BAD_INDEX;
431667102f6b072582fe497599e0b760f9fc94ceffaMathias Agopian    }
432724d91d778e71c8186399f4955de14b54812b3edAravind Akella    BatchParams& params = batchParams.editValueAt(index);
433724d91d778e71c8186399f4955de14b54812b3edAravind Akella    params.flags = flags;
434724d91d778e71c8186399f4955de14b54812b3edAravind Akella    params.batchDelay = samplingPeriodNs;
435724d91d778e71c8186399f4955de14b54812b3edAravind Akella    params.batchTimeout = maxBatchReportLatencyNs;
436667102f6b072582fe497599e0b760f9fc94ceffaMathias Agopian    return NO_ERROR;
437667102f6b072582fe497599e0b760f9fc94ceffaMathias Agopian}
438667102f6b072582fe497599e0b760f9fc94ceffaMathias Agopian
439724d91d778e71c8186399f4955de14b54812b3edAravind Akellavoid SensorDevice::Info::selectBatchParams() {
4404949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    BatchParams bestParams(0, -1, -1);
4414949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    SensorDevice& device(SensorDevice::getInstance());
442724d91d778e71c8186399f4955de14b54812b3edAravind Akella
4434949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    for (size_t i = 0; i < batchParams.size(); ++i) {
4444949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        if (device.isClientDisabledLocked(batchParams.keyAt(i))) continue;
445724d91d778e71c8186399f4955de14b54812b3edAravind Akella        BatchParams params = batchParams.valueAt(i);
4464949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        if (bestParams.batchDelay == -1 || params.batchDelay < bestParams.batchDelay) {
447724d91d778e71c8186399f4955de14b54812b3edAravind Akella            bestParams.batchDelay = params.batchDelay;
448724d91d778e71c8186399f4955de14b54812b3edAravind Akella        }
4494949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        if (bestParams.batchTimeout == -1 || params.batchTimeout < bestParams.batchTimeout) {
450724d91d778e71c8186399f4955de14b54812b3edAravind Akella            bestParams.batchTimeout = params.batchTimeout;
451667102f6b072582fe497599e0b760f9fc94ceffaMathias Agopian        }
452667102f6b072582fe497599e0b760f9fc94ceffaMathias Agopian    }
453724d91d778e71c8186399f4955de14b54812b3edAravind Akella    bestBatchParams = bestParams;
454724d91d778e71c8186399f4955de14b54812b3edAravind Akella}
455724d91d778e71c8186399f4955de14b54812b3edAravind Akella
456724d91d778e71c8186399f4955de14b54812b3edAravind Akellassize_t SensorDevice::Info::removeBatchParamsForIdent(void* ident) {
457724d91d778e71c8186399f4955de14b54812b3edAravind Akella    ssize_t idx = batchParams.removeItem(ident);
458724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (idx >= 0) {
459724d91d778e71c8186399f4955de14b54812b3edAravind Akella        selectBatchParams();
460724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
461724d91d778e71c8186399f4955de14b54812b3edAravind Akella    return idx;
462f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
463f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
464f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian// ---------------------------------------------------------------------------
465f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}; // namespace android
466f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
467