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 */
163889e6ea1c321cbaf8a959775da58509672143afPeng Xu#include "SensorDevice.h"
173889e6ea1c321cbaf8a959775da58509672143afPeng Xu#include "SensorService.h"
18d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland
19d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland#include <android-base/logging.h>
203889e6ea1c321cbaf8a959775da58509672143afPeng Xu#include <sensors/convert.h>
21d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland#include <utils/Atomic.h>
22d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland#include <utils/Errors.h>
23d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland#include <utils/Singleton.h>
24f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
253889e6ea1c321cbaf8a959775da58509672143afPeng Xu#include <chrono>
263889e6ea1c321cbaf8a959775da58509672143afPeng Xu#include <cinttypes>
273889e6ea1c321cbaf8a959775da58509672143afPeng Xu#include <thread>
28f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
29d15c030f7255ec9db8567a4ee77a56844982586dSteven Morelandusing android::hardware::hidl_vec;
30f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
31d15c030f7255ec9db8567a4ee77a56844982586dSteven Morelandusing namespace android::hardware::sensors::V1_0;
32d15c030f7255ec9db8567a4ee77a56844982586dSteven Morelandusing namespace android::hardware::sensors::V1_0::implementation;
33f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
342bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu
35f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopiannamespace android {
36f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian// ---------------------------------------------------------------------------
37f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
38f001c92436b4a66eb7687286325ced7f10c9f917Mathias AgopianANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice)
39f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
40d15c030f7255ec9db8567a4ee77a56844982586dSteven Morelandstatic status_t StatusFromResult(Result result) {
41d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    switch (result) {
42d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        case Result::OK:
43d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            return OK;
44d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        case Result::BAD_VALUE:
45d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            return BAD_VALUE;
46d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        case Result::PERMISSION_DENIED:
47d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            return PERMISSION_DENIED;
48d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        case Result::INVALID_OPERATION:
49d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            return INVALID_OPERATION;
50d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        case Result::NO_MEMORY:
51d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            return NO_MEMORY;
52d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    }
53d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland}
54f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
5596b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh JoshiSensorDevice::SensorDevice() : mHidlTransportErrors(20) {
56a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    if (!connectHidlService()) {
57a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu        return;
58a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    }
59fea2d26f964f2e8065e462429766fd7dcf227275Ashutosh Joshi
60fea2d26f964f2e8065e462429766fd7dcf227275Ashutosh Joshi    float minPowerMa = 0.001; // 1 microAmp
61fea2d26f964f2e8065e462429766fd7dcf227275Ashutosh Joshi
62a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    checkReturn(mSensors->getSensorsList(
63a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu            [&](const auto &list) {
64a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu                const size_t count = list.size();
65a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu
66a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu                mActivationCount.setCapacity(count);
67a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu                Info model;
68a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu                for (size_t i=0 ; i < count; i++) {
69a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu                    sensor_t sensor;
70a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu                    convertToSensor(list[i], &sensor);
71fea2d26f964f2e8065e462429766fd7dcf227275Ashutosh Joshi                    // Sanity check and clamp power if it is 0 (or close)
72fea2d26f964f2e8065e462429766fd7dcf227275Ashutosh Joshi                    if (sensor.power < minPowerMa) {
73fea2d26f964f2e8065e462429766fd7dcf227275Ashutosh Joshi                        ALOGE("Reported power %f not deemed sane, clamping to %f",
74fea2d26f964f2e8065e462429766fd7dcf227275Ashutosh Joshi                              sensor.power, minPowerMa);
75fea2d26f964f2e8065e462429766fd7dcf227275Ashutosh Joshi                        sensor.power = minPowerMa;
76fea2d26f964f2e8065e462429766fd7dcf227275Ashutosh Joshi                    }
77a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu                    mSensorList.push_back(sensor);
78a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu
79a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu                    mActivationCount.add(list[i].sensorHandle, model);
80a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu
81a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu                    checkReturn(mSensors->activate(list[i].sensorHandle, 0 /* enabled */));
82a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu                }
83a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu            }));
84a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu
85a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    mIsDirectReportSupported =
86a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu           (checkReturn(mSensors->unregisterDirectChannel(-1)) != Result::INVALID_OPERATION);
87a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu}
88a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu
89a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xubool SensorDevice::connectHidlService() {
903889e6ea1c321cbaf8a959775da58509672143afPeng Xu    // SensorDevice may wait upto 100ms * 10 = 1s for hidl service.
913889e6ea1c321cbaf8a959775da58509672143afPeng Xu    constexpr auto RETRY_DELAY = std::chrono::milliseconds(100);
923889e6ea1c321cbaf8a959775da58509672143afPeng Xu    size_t retry = 10;
933889e6ea1c321cbaf8a959775da58509672143afPeng Xu
943889e6ea1c321cbaf8a959775da58509672143afPeng Xu    while (true) {
953889e6ea1c321cbaf8a959775da58509672143afPeng Xu        int initStep = 0;
963889e6ea1c321cbaf8a959775da58509672143afPeng Xu        mSensors = ISensors::getService();
973889e6ea1c321cbaf8a959775da58509672143afPeng Xu        if (mSensors != nullptr) {
983889e6ea1c321cbaf8a959775da58509672143afPeng Xu            ++initStep;
993889e6ea1c321cbaf8a959775da58509672143afPeng Xu            // Poke ISensor service. If it has lingering connection from previous generation of
1003889e6ea1c321cbaf8a959775da58509672143afPeng Xu            // system server, it will kill itself. There is no intention to handle the poll result,
1013889e6ea1c321cbaf8a959775da58509672143afPeng Xu            // which will be done since the size is 0.
1023889e6ea1c321cbaf8a959775da58509672143afPeng Xu            if(mSensors->poll(0, [](auto, const auto &, const auto &) {}).isOk()) {
1033889e6ea1c321cbaf8a959775da58509672143afPeng Xu                // ok to continue
1043889e6ea1c321cbaf8a959775da58509672143afPeng Xu                break;
1053889e6ea1c321cbaf8a959775da58509672143afPeng Xu            }
1063889e6ea1c321cbaf8a959775da58509672143afPeng Xu            // hidl service is restarting, pointer is invalid.
1073889e6ea1c321cbaf8a959775da58509672143afPeng Xu            mSensors = nullptr;
1083889e6ea1c321cbaf8a959775da58509672143afPeng Xu        }
109f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
1103889e6ea1c321cbaf8a959775da58509672143afPeng Xu        if (--retry <= 0) {
1113889e6ea1c321cbaf8a959775da58509672143afPeng Xu            ALOGE("Cannot connect to ISensors hidl service!");
112a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu            break;
1133889e6ea1c321cbaf8a959775da58509672143afPeng Xu        }
1143889e6ea1c321cbaf8a959775da58509672143afPeng Xu        // Delay 100ms before retry, hidl service is expected to come up in short time after
1153889e6ea1c321cbaf8a959775da58509672143afPeng Xu        // crash.
1163889e6ea1c321cbaf8a959775da58509672143afPeng Xu        ALOGI("%s unsuccessful, try again soon (remaining retry %zu).",
1173889e6ea1c321cbaf8a959775da58509672143afPeng Xu                (initStep == 0) ? "getService()" : "poll() check", retry);
1183889e6ea1c321cbaf8a959775da58509672143afPeng Xu        std::this_thread::sleep_for(RETRY_DELAY);
119d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    }
120a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    return (mSensors != nullptr);
121f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
122f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
1232576cb63b3fe1592f54816625036566b9eb0793aPeng Xuvoid SensorDevice::handleDynamicSensorConnection(int handle, bool connected) {
124a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    // not need to check mSensors because this is is only called after successful poll()
1252576cb63b3fe1592f54816625036566b9eb0793aPeng Xu    if (connected) {
1262576cb63b3fe1592f54816625036566b9eb0793aPeng Xu        Info model;
1272576cb63b3fe1592f54816625036566b9eb0793aPeng Xu        mActivationCount.add(handle, model);
1283889e6ea1c321cbaf8a959775da58509672143afPeng Xu        checkReturn(mSensors->activate(handle, 0 /* enabled */));
1292576cb63b3fe1592f54816625036566b9eb0793aPeng Xu    } else {
1302576cb63b3fe1592f54816625036566b9eb0793aPeng Xu        mActivationCount.removeItem(handle);
1312576cb63b3fe1592f54816625036566b9eb0793aPeng Xu    }
1322576cb63b3fe1592f54816625036566b9eb0793aPeng Xu}
1332576cb63b3fe1592f54816625036566b9eb0793aPeng Xu
1346a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xustd::string SensorDevice::dump() const {
135a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    if (mSensors == nullptr) return "HAL not initialized\n";
1366a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
1376a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    String8 result;
138a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    result.appendFormat("Total %zu h/w sensors, %zu running:\n",
139a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu                        mSensorList.size(), mActivationCount.size());
14096b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi
141a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    Mutex::Autolock _l(mLock);
142a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    for (const auto & s : mSensorList) {
143a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu        int32_t handle = s.handle;
144a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu        const Info& info = mActivationCount.valueFor(handle);
145a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu        if (info.batchParams.isEmpty()) continue;
14696b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi
147a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu        result.appendFormat("0x%08x) active-count = %zu; ", handle, info.batchParams.size());
148d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland
149a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu        result.append("sampling_period(ms) = {");
150a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu        for (size_t j = 0; j < info.batchParams.size(); j++) {
1512bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu            const BatchParams& params = info.batchParams[j];
1522bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu            result.appendFormat("%.1f%s", params.mTSample / 1e6f,
153a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu                j < info.batchParams.size() - 1 ? ", " : "");
154a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu        }
1552bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu        result.appendFormat("}, selected = %.2f ms; ", info.bestBatchParams.mTSample / 1e6f);
156724d91d778e71c8186399f4955de14b54812b3edAravind Akella
157a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu        result.append("batching_period(ms) = {");
158a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu        for (size_t j = 0; j < info.batchParams.size(); j++) {
1592bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu            const BatchParams& params = info.batchParams[j];
1602bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu            result.appendFormat("%.1f%s", params.mTBatch / 1e6f,
161a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu                    j < info.batchParams.size() - 1 ? ", " : "");
162a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu        }
1632bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu        result.appendFormat("}, selected = %.2f ms\n", info.bestBatchParams.mTBatch / 1e6f);
164a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    }
1655cafc1e086db67911f937b68d35f0955e0a37cafAshutosh Joshi
1666a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    return result.string();
167f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
168f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
169f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopianssize_t SensorDevice::getSensorList(sensor_t const** list) {
170d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    *list = &mSensorList[0];
171d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland
172d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    return mSensorList.size();
173f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
174f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
175f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopianstatus_t SensorDevice::initCheck() const {
176d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    return mSensors != NULL ? NO_ERROR : NO_INIT;
177f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
178f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
179f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopianssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
180a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    if (mSensors == nullptr) return NO_INIT;
181d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland
182d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    ssize_t err;
18396b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi    int numHidlTransportErrors = 0;
18496b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi    bool hidlTransportError = false;
185d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland
18696b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi    do {
18796b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi        auto ret = mSensors->poll(
18896b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi                count,
18996b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi                [&](auto result,
19096b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi                    const auto &events,
19196b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi                    const auto &dynamicSensorsAdded) {
19296b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi                    if (result == Result::OK) {
19396b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi                        convertToSensorEvents(events, dynamicSensorsAdded, buffer);
19496b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi                        err = (ssize_t)events.size();
19596b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi                    } else {
19696b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi                        err = StatusFromResult(result);
19796b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi                    }
19896b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi                });
19996b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi
20096b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi        if (ret.isOk())  {
20196b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi            hidlTransportError = false;
20296b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi        } else {
20396b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi            hidlTransportError = true;
20496b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi            numHidlTransportErrors++;
20596b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi            if (numHidlTransportErrors > 50) {
20696b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi                // Log error and bail
20796b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi                ALOGE("Max Hidl transport errors this cycle : %d", numHidlTransportErrors);
20896b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi                handleHidlDeath(ret.description());
20996b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi            } else {
21096b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi                std::this_thread::sleep_for(std::chrono::milliseconds(10));
21196b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi            }
21296b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi        }
21396b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi    } while (hidlTransportError);
21496b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi
21596b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi    if(numHidlTransportErrors > 0) {
21696b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi        ALOGE("Saw %d Hidl transport failures", numHidlTransportErrors);
21796b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi        HidlTransportErrorLog errLog(time(NULL), numHidlTransportErrors);
21896b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi        mHidlTransportErrors.add(errLog);
21996b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi        mTotalHidlTransportErrors++;
22096b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi    }
221d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland
222d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    return err;
223f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
224f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
225ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopianvoid SensorDevice::autoDisable(void *ident, int handle) {
226ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian    Info& info( mActivationCount.editValueFor(handle) );
2274c01b1ad80e084f0cd1057f89fdd1fcedf19dd96Jaikumar Ganesh    Mutex::Autolock _l(mLock);
228724d91d778e71c8186399f4955de14b54812b3edAravind Akella    info.removeBatchParamsForIdent(ident);
2294c01b1ad80e084f0cd1057f89fdd1fcedf19dd96Jaikumar Ganesh}
2304c01b1ad80e084f0cd1057f89fdd1fcedf19dd96Jaikumar Ganesh
2316a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xustatus_t SensorDevice::activate(void* ident, int handle, int enabled) {
232a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    if (mSensors == nullptr) return NO_INIT;
233d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland
234f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    status_t err(NO_ERROR);
235f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    bool actuateHardware = false;
236f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
237724d91d778e71c8186399f4955de14b54812b3edAravind Akella    Mutex::Autolock _l(mLock);
238f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    Info& info( mActivationCount.editValueFor(handle) );
239a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian
240a551237de142549fb8a6608ee9d2fbf4b7ca2ebfSteve Block    ALOGD_IF(DEBUG_CONNECTIONS,
241db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn             "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%zu",
242724d91d778e71c8186399f4955de14b54812b3edAravind Akella             ident, handle, enabled, info.batchParams.size());
243a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian
244f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    if (enabled) {
245db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn        ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%zd", info.batchParams.indexOfKey(ident));
246a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian
2474949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        if (isClientDisabledLocked(ident)) {
248966fa88493d782f2ae63f1e4bae2182659ebfe6ePeng Xu            ALOGE("SensorDevice::activate, isClientDisabledLocked(%p):true, handle:%d",
249966fa88493d782f2ae63f1e4bae2182659ebfe6ePeng Xu                    ident, handle);
2504949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            return INVALID_OPERATION;
2514949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        }
2524949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
253724d91d778e71c8186399f4955de14b54812b3edAravind Akella        if (info.batchParams.indexOfKey(ident) >= 0) {
2544949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella          if (info.numActiveClients() == 1) {
255724d91d778e71c8186399f4955de14b54812b3edAravind Akella              // This is the first connection, we need to activate the underlying h/w sensor.
256724d91d778e71c8186399f4955de14b54812b3edAravind Akella              actuateHardware = true;
257724d91d778e71c8186399f4955de14b54812b3edAravind Akella          }
25850b66767f6c5635430483393e17d15969dfe2f05Mathias Agopian        } else {
259724d91d778e71c8186399f4955de14b54812b3edAravind Akella            // Log error. Every activate call should be preceded by a batch() call.
260724d91d778e71c8186399f4955de14b54812b3edAravind Akella            ALOGE("\t >>>ERROR: activate called without batch");
261f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian        }
26250b66767f6c5635430483393e17d15969dfe2f05Mathias Agopian    } else {
263db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn        ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident));
264a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian
265d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        // If a connected dynamic sensor is deactivated, remove it from the
266d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        // dictionary.
267d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        auto it = mConnectedDynamicSensors.find(handle);
268d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        if (it != mConnectedDynamicSensors.end()) {
269d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            delete it->second;
270d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            mConnectedDynamicSensors.erase(it);
271d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        }
272d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland
273724d91d778e71c8186399f4955de14b54812b3edAravind Akella        if (info.removeBatchParamsForIdent(ident) >= 0) {
2744949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            if (info.numActiveClients() == 0) {
275724d91d778e71c8186399f4955de14b54812b3edAravind Akella                // This is the last connection, we need to de-activate the underlying h/w sensor.
27650b66767f6c5635430483393e17d15969dfe2f05Mathias Agopian                actuateHardware = true;
277724d91d778e71c8186399f4955de14b54812b3edAravind Akella            } else {
278d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland                // Call batch for this sensor with the previously calculated best effort
279d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland                // batch_rate and timeout. One of the apps has unregistered for sensor
280d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland                // events, and the best effort batch parameters might have changed.
281d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland                ALOGD_IF(DEBUG_CONNECTIONS,
2822bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu                         "\t>>> actuating h/w batch 0x%08x %" PRId64 " %" PRId64, handle,
2832bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu                         info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch);
2843889e6ea1c321cbaf8a959775da58509672143afPeng Xu                checkReturn(mSensors->batch(
2852bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu                        handle, info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch));
28650b66767f6c5635430483393e17d15969dfe2f05Mathias Agopian            }
28750b66767f6c5635430483393e17d15969dfe2f05Mathias Agopian        } else {
28850b66767f6c5635430483393e17d15969dfe2f05Mathias Agopian            // sensor wasn't enabled for this ident
28950b66767f6c5635430483393e17d15969dfe2f05Mathias Agopian        }
2904949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
2914949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        if (isClientDisabledLocked(ident)) {
2924949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            return NO_ERROR;
2934949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        }
294f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    }
29550b66767f6c5635430483393e17d15969dfe2f05Mathias Agopian
296f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    if (actuateHardware) {
2974949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
2984949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella                 enabled);
2993889e6ea1c321cbaf8a959775da58509672143afPeng Xu        err = StatusFromResult(checkReturn(mSensors->activate(handle, enabled)));
300724d91d778e71c8186399f4955de14b54812b3edAravind Akella        ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
301724d91d778e71c8186399f4955de14b54812b3edAravind Akella                 strerror(-err));
302724d91d778e71c8186399f4955de14b54812b3edAravind Akella
303724d91d778e71c8186399f4955de14b54812b3edAravind Akella        if (err != NO_ERROR && enabled) {
304724d91d778e71c8186399f4955de14b54812b3edAravind Akella            // Failure when enabling the sensor. Clean up on failure.
305724d91d778e71c8186399f4955de14b54812b3edAravind Akella            info.removeBatchParamsForIdent(ident);
306724d91d778e71c8186399f4955de14b54812b3edAravind Akella        }
307724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
308a1b7db95b6ccf5be9d8dfaac1b8f45494813edc0Mathias Agopian
309724d91d778e71c8186399f4955de14b54812b3edAravind Akella    return err;
310724d91d778e71c8186399f4955de14b54812b3edAravind Akella}
311ac9a96da65f6eae4513654adaad8a457d1c1575cMathias Agopian
312d15c030f7255ec9db8567a4ee77a56844982586dSteven Morelandstatus_t SensorDevice::batch(
313d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        void* ident,
314d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        int handle,
315d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        int flags,
316d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        int64_t samplingPeriodNs,
317d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        int64_t maxBatchReportLatencyNs) {
318a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    if (mSensors == nullptr) return NO_INIT;
319724d91d778e71c8186399f4955de14b54812b3edAravind Akella
320724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
321724d91d778e71c8186399f4955de14b54812b3edAravind Akella        samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
322724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
3232bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu    if (maxBatchReportLatencyNs < 0) {
3242bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu        maxBatchReportLatencyNs = 0;
3252bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu    }
326724d91d778e71c8186399f4955de14b54812b3edAravind Akella
327724d91d778e71c8186399f4955de14b54812b3edAravind Akella    ALOGD_IF(DEBUG_CONNECTIONS,
328db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn             "SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%" PRId64 " timeout=%" PRId64,
329724d91d778e71c8186399f4955de14b54812b3edAravind Akella             ident, handle, flags, samplingPeriodNs, maxBatchReportLatencyNs);
330724d91d778e71c8186399f4955de14b54812b3edAravind Akella
331724d91d778e71c8186399f4955de14b54812b3edAravind Akella    Mutex::Autolock _l(mLock);
332724d91d778e71c8186399f4955de14b54812b3edAravind Akella    Info& info(mActivationCount.editValueFor(handle));
333724d91d778e71c8186399f4955de14b54812b3edAravind Akella
334724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (info.batchParams.indexOfKey(ident) < 0) {
3352bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu        BatchParams params(samplingPeriodNs, maxBatchReportLatencyNs);
336724d91d778e71c8186399f4955de14b54812b3edAravind Akella        info.batchParams.add(ident, params);
337724d91d778e71c8186399f4955de14b54812b3edAravind Akella    } else {
338724d91d778e71c8186399f4955de14b54812b3edAravind Akella        // A batch has already been called with this ident. Update the batch parameters.
339724d91d778e71c8186399f4955de14b54812b3edAravind Akella        info.setBatchParamsForIdent(ident, flags, samplingPeriodNs, maxBatchReportLatencyNs);
340f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    }
341f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
342724d91d778e71c8186399f4955de14b54812b3edAravind Akella    BatchParams prevBestBatchParams = info.bestBatchParams;
343724d91d778e71c8186399f4955de14b54812b3edAravind Akella    // Find the minimum of all timeouts and batch_rates for this sensor.
344724d91d778e71c8186399f4955de14b54812b3edAravind Akella    info.selectBatchParams();
345724d91d778e71c8186399f4955de14b54812b3edAravind Akella
346724d91d778e71c8186399f4955de14b54812b3edAravind Akella    ALOGD_IF(DEBUG_CONNECTIONS,
347db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn             "\t>>> curr_period=%" PRId64 " min_period=%" PRId64
348db45861ff4b636b9dd833d622dd64e2ad24b0645Mark Salyzyn             " curr_timeout=%" PRId64 " min_timeout=%" PRId64,
3492bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu             prevBestBatchParams.mTSample, info.bestBatchParams.mTSample,
3502bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu             prevBestBatchParams.mTBatch, info.bestBatchParams.mTBatch);
351724d91d778e71c8186399f4955de14b54812b3edAravind Akella
352724d91d778e71c8186399f4955de14b54812b3edAravind Akella    status_t err(NO_ERROR);
353724d91d778e71c8186399f4955de14b54812b3edAravind Akella    // If the min period or min timeout has changed since the last batch call, call batch.
354724d91d778e71c8186399f4955de14b54812b3edAravind Akella    if (prevBestBatchParams != info.bestBatchParams) {
3552bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu        ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH 0x%08x %" PRId64 " %" PRId64, handle,
3562bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu                 info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch);
357d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        err = StatusFromResult(
3583889e6ea1c321cbaf8a959775da58509672143afPeng Xu                checkReturn(mSensors->batch(
3592bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu                    handle, info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch)));
360724d91d778e71c8186399f4955de14b54812b3edAravind Akella        if (err != NO_ERROR) {
3612bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu            ALOGE("sensor batch failed %p 0x%08x %" PRId64 " %" PRId64 " err=%s",
3622bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu                  mSensors.get(), handle, info.bestBatchParams.mTSample,
3632bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu                  info.bestBatchParams.mTBatch, strerror(-err));
364724d91d778e71c8186399f4955de14b54812b3edAravind Akella            info.removeBatchParamsForIdent(ident);
365724d91d778e71c8186399f4955de14b54812b3edAravind Akella        }
366724d91d778e71c8186399f4955de14b54812b3edAravind Akella    }
367f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    return err;
368f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}
369f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
3706a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xustatus_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs) {
3712bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu    return batch(ident, handle, 0, samplingPeriodNs, 0);
372667102f6b072582fe497599e0b760f9fc94ceffaMathias Agopian}
373984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian
3744342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganeshint SensorDevice::getHalDeviceVersion() const {
375a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    if (mSensors == nullptr) return -1;
376d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    return SENSORS_DEVICE_API_VERSION_1_4;
3774342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh}
3784342fdf14ffb792a36c1de25ad14b745df628da2Jaikumar Ganesh
3799a844cf78f09953145200b4074d47589257a408cAravind Akellastatus_t SensorDevice::flush(void* ident, int handle) {
380a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    if (mSensors == nullptr) return NO_INIT;
3814949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    if (isClientDisabled(ident)) return INVALID_OPERATION;
382724d91d778e71c8186399f4955de14b54812b3edAravind Akella    ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle);
3833889e6ea1c321cbaf8a959775da58509672143afPeng Xu    return StatusFromResult(checkReturn(mSensors->flush(handle)));
384724d91d778e71c8186399f4955de14b54812b3edAravind Akella}
385724d91d778e71c8186399f4955de14b54812b3edAravind Akella
3864949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akellabool SensorDevice::isClientDisabled(void* ident) {
3874949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    Mutex::Autolock _l(mLock);
3884949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    return isClientDisabledLocked(ident);
3894949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella}
3904949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
3914949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akellabool SensorDevice::isClientDisabledLocked(void* ident) {
3924949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    return mDisabledClients.indexOf(ident) >= 0;
3934949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella}
3944949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
3954949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akellavoid SensorDevice::enableAllSensors() {
396a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    if (mSensors == nullptr) return;
3974949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    Mutex::Autolock _l(mLock);
3984949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    mDisabledClients.clear();
399966fa88493d782f2ae63f1e4bae2182659ebfe6ePeng Xu    ALOGI("cleared mDisabledClients");
4004949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    for (size_t i = 0; i< mActivationCount.size(); ++i) {
4014949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        Info& info = mActivationCount.editValueAt(i);
4024949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        if (info.batchParams.isEmpty()) continue;
4034949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        info.selectBatchParams();
4044949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        const int sensor_handle = mActivationCount.keyAt(i);
4054949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        ALOGD_IF(DEBUG_CONNECTIONS, "\t>> reenable actuating h/w sensor enable handle=%d ",
4064949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella                   sensor_handle);
407d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        status_t err = StatusFromResult(
4083889e6ea1c321cbaf8a959775da58509672143afPeng Xu                checkReturn(mSensors->batch(
409d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland                    sensor_handle,
4102bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu                    info.bestBatchParams.mTSample,
4112bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu                    info.bestBatchParams.mTBatch)));
412d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        ALOGE_IF(err, "Error calling batch on sensor %d (%s)", sensor_handle, strerror(-err));
4134949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
4144949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        if (err == NO_ERROR) {
415d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            err = StatusFromResult(
4163889e6ea1c321cbaf8a959775da58509672143afPeng Xu                    checkReturn(mSensors->activate(sensor_handle, 1 /* enabled */)));
4174949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella            ALOGE_IF(err, "Error activating sensor %d (%s)", sensor_handle, strerror(-err));
4184949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        }
4194949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    }
4204949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella}
4214949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
4224949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akellavoid SensorDevice::disableAllSensors() {
423a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    if (mSensors == nullptr) return;
4244949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    Mutex::Autolock _l(mLock);
425a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    for (size_t i = 0; i< mActivationCount.size(); ++i) {
4264949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        const Info& info = mActivationCount.valueAt(i);
4274949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        // Check if this sensor has been activated previously and disable it.
4284949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        if (info.batchParams.size() > 0) {
4294949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella           const int sensor_handle = mActivationCount.keyAt(i);
4304949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella           ALOGD_IF(DEBUG_CONNECTIONS, "\t>> actuating h/w sensor disable handle=%d ",
4314949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella                   sensor_handle);
4323889e6ea1c321cbaf8a959775da58509672143afPeng Xu           checkReturn(mSensors->activate(sensor_handle, 0 /* enabled */));
433d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland
4344949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella           // Add all the connections that were registered for this sensor to the disabled
4354949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella           // clients list.
436b412f6e203b38f8047f760261a5e3dc6d0722f08Svetoslav           for (size_t j = 0; j < info.batchParams.size(); ++j) {
4374949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella               mDisabledClients.add(info.batchParams.keyAt(j));
438966fa88493d782f2ae63f1e4bae2182659ebfe6ePeng Xu               ALOGI("added %p to mDisabledClients", info.batchParams.keyAt(j));
4394949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella           }
4404949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        }
4414949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    }
4424949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella}
4434949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
444d15c030f7255ec9db8567a4ee77a56844982586dSteven Morelandstatus_t SensorDevice::injectSensorData(
445d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        const sensors_event_t *injected_sensor_event) {
446a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    if (mSensors == nullptr) return NO_INIT;
447d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    ALOGD_IF(DEBUG_CONNECTIONS,
448d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            "sensor_event handle=%d ts=%" PRId64 " data=%.2f, %.2f, %.2f %.2f %.2f %.2f",
449d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            injected_sensor_event->sensor,
450d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            injected_sensor_event->timestamp, injected_sensor_event->data[0],
451d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            injected_sensor_event->data[1], injected_sensor_event->data[2],
452d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            injected_sensor_event->data[3], injected_sensor_event->data[4],
453d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            injected_sensor_event->data[5]);
454d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland
455d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    Event ev;
456d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    convertFromSensorEvent(*injected_sensor_event, &ev);
457d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland
4583889e6ea1c321cbaf8a959775da58509672143afPeng Xu    return StatusFromResult(checkReturn(mSensors->injectSensorData(ev)));
459a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella}
460a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akella
461a9e6cc387072e25706a6d847a97b02a6f25a918bAravind Akellastatus_t SensorDevice::setMode(uint32_t mode) {
462a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    if (mSensors == nullptr) return NO_INIT;
463a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    return StatusFromResult(
464a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu            checkReturn(mSensors->setOperationMode(
465a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu                    static_cast<hardware::sensors::V1_0::OperationMode>(mode))));
4664f707f8b3da68d3055db895da9ae5216cc4f483aPeng Xu}
4674f707f8b3da68d3055db895da9ae5216cc4f483aPeng Xu
468e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xuint32_t SensorDevice::registerDirectChannel(const sensors_direct_mem_t* memory) {
469a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    if (mSensors == nullptr) return NO_INIT;
470d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    Mutex::Autolock _l(mLock);
4715363254ba38b50da95e5bdb15391c139c182627cPeng Xu
472d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    SharedMemType type;
473d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    switch (memory->type) {
474d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        case SENSOR_DIRECT_MEM_TYPE_ASHMEM:
475d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            type = SharedMemType::ASHMEM;
476d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            break;
477d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
478d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            type = SharedMemType::GRALLOC;
479d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            break;
480d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        default:
481d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            return BAD_VALUE;
4825363254ba38b50da95e5bdb15391c139c182627cPeng Xu    }
4835363254ba38b50da95e5bdb15391c139c182627cPeng Xu
484d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    SharedMemFormat format;
485d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    if (memory->format != SENSOR_DIRECT_FMT_SENSORS_EVENT) {
486d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        return BAD_VALUE;
487d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    }
488d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    format = SharedMemFormat::SENSORS_EVENT;
489d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland
490d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    SharedMemInfo mem = {
491d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        .type = type,
492d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        .format = format,
493d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        .size = static_cast<uint32_t>(memory->size),
494d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        .memoryHandle = memory->handle,
495d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    };
496d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland
497d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    int32_t ret;
4983889e6ea1c321cbaf8a959775da58509672143afPeng Xu    checkReturn(mSensors->registerDirectChannel(mem,
499d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            [&ret](auto result, auto channelHandle) {
500d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland                if (result == Result::OK) {
501d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland                    ret = channelHandle;
502d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland                } else {
503d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland                    ret = StatusFromResult(result);
504d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland                }
5053889e6ea1c321cbaf8a959775da58509672143afPeng Xu            }));
506d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    return ret;
507e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu}
508e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu
509e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xuvoid SensorDevice::unregisterDirectChannel(int32_t channelHandle) {
510a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    if (mSensors == nullptr) return;
511e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    Mutex::Autolock _l(mLock);
5123889e6ea1c321cbaf8a959775da58509672143afPeng Xu    checkReturn(mSensors->unregisterDirectChannel(channelHandle));
513e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu}
514e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu
515d15c030f7255ec9db8567a4ee77a56844982586dSteven Morelandint32_t SensorDevice::configureDirectChannel(int32_t sensorHandle,
516d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        int32_t channelHandle, const struct sensors_direct_cfg_t *config) {
517a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    if (mSensors == nullptr) return NO_INIT;
518d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    Mutex::Autolock _l(mLock);
5195363254ba38b50da95e5bdb15391c139c182627cPeng Xu
520d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    RateLevel rate;
521d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    switch(config->rate_level) {
522d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        case SENSOR_DIRECT_RATE_STOP:
523d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            rate = RateLevel::STOP;
524d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            break;
525d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        case SENSOR_DIRECT_RATE_NORMAL:
526d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            rate = RateLevel::NORMAL;
527d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            break;
528d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        case SENSOR_DIRECT_RATE_FAST:
529d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            rate = RateLevel::FAST;
530d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            break;
531d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        case SENSOR_DIRECT_RATE_VERY_FAST:
532d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            rate = RateLevel::VERY_FAST;
533d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            break;
534d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        default:
535d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            return BAD_VALUE;
5365363254ba38b50da95e5bdb15391c139c182627cPeng Xu    }
5375363254ba38b50da95e5bdb15391c139c182627cPeng Xu
538d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    int32_t ret;
5393889e6ea1c321cbaf8a959775da58509672143afPeng Xu    checkReturn(mSensors->configDirectReport(sensorHandle, channelHandle, rate,
540d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            [&ret, rate] (auto result, auto token) {
541d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland                if (rate == RateLevel::STOP) {
542d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland                    ret = StatusFromResult(result);
543d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland                } else {
544d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland                    if (result == Result::OK) {
545d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland                        ret = token;
546d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland                    } else {
547d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland                        ret = StatusFromResult(result);
548d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland                    }
549d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland                }
5503889e6ea1c321cbaf8a959775da58509672143afPeng Xu            }));
551e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu
552e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    return ret;
553e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu}
5545363254ba38b50da95e5bdb15391c139c182627cPeng Xu
555a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu// ---------------------------------------------------------------------------
556a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu
557a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xuint SensorDevice::Info::numActiveClients() {
558a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    SensorDevice& device(SensorDevice::getInstance());
559a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    int num = 0;
560a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    for (size_t i = 0; i < batchParams.size(); ++i) {
561a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu        if (!device.isClientDisabledLocked(batchParams.keyAt(i))) {
562a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu            ++num;
563a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu        }
564a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    }
565a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    return num;
566a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu}
567a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu
5682bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xustatus_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int,
569a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu                                                    int64_t samplingPeriodNs,
570a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu                                                    int64_t maxBatchReportLatencyNs) {
571a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    ssize_t index = batchParams.indexOfKey(ident);
572a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    if (index < 0) {
5732bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu        ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%" PRId64
5742bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu              " timeout=%" PRId64 ") failed (%s)",
575a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu              ident, samplingPeriodNs, maxBatchReportLatencyNs, strerror(-index));
576a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu        return BAD_INDEX;
577a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    }
578a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    BatchParams& params = batchParams.editValueAt(index);
5792bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu    params.mTSample = samplingPeriodNs;
5802bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu    params.mTBatch = maxBatchReportLatencyNs;
581a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    return NO_ERROR;
582a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu}
583a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu
584a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xuvoid SensorDevice::Info::selectBatchParams() {
5852bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu    BatchParams bestParams; // default to max Tsample and max Tbatch
586a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    SensorDevice& device(SensorDevice::getInstance());
587a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu
588a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    for (size_t i = 0; i < batchParams.size(); ++i) {
5892bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu        if (device.isClientDisabledLocked(batchParams.keyAt(i))) {
5902bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu            continue;
591a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu        }
5922bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu        bestParams.merge(batchParams[i]);
5932bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu    }
5942bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu    // if mTBatch <= mTSample, it is in streaming mode. set mTbatch to 0 to demand this explicitly.
5952bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu    if (bestParams.mTBatch <= bestParams.mTSample) {
5962bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu        bestParams.mTBatch = 0;
597a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    }
598a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    bestBatchParams = bestParams;
599a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu}
600a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu
601a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xussize_t SensorDevice::Info::removeBatchParamsForIdent(void* ident) {
602a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    ssize_t idx = batchParams.removeItem(ident);
603a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    if (idx >= 0) {
604a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu        selectBatchParams();
605a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    }
606a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    return idx;
607a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu}
608a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu
609a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xuvoid SensorDevice::notifyConnectionDestroyed(void* ident) {
610a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    Mutex::Autolock _l(mLock);
611a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    mDisabledClients.remove(ident);
612a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu}
613a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu
6145363254ba38b50da95e5bdb15391c139c182627cPeng Xubool SensorDevice::isDirectReportSupported() const {
615d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    return mIsDirectReportSupported;
616d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland}
617d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland
618d15c030f7255ec9db8567a4ee77a56844982586dSteven Morelandvoid SensorDevice::convertToSensorEvent(
619d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        const Event &src, sensors_event_t *dst) {
620d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    ::android::hardware::sensors::V1_0::implementation::convertToSensorEvent(
621d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            src, dst);
622d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland
623d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    if (src.sensorType == SensorType::DYNAMIC_SENSOR_META) {
624d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        const DynamicSensorInfo &dyn = src.u.dynamic;
625d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland
626d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        dst->dynamic_sensor_meta.connected = dyn.connected;
627d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        dst->dynamic_sensor_meta.handle = dyn.sensorHandle;
628d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        if (dyn.connected) {
629d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            auto it = mConnectedDynamicSensors.find(dyn.sensorHandle);
630d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            CHECK(it != mConnectedDynamicSensors.end());
631d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland
632d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            dst->dynamic_sensor_meta.sensor = it->second;
633d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland
634d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland            memcpy(dst->dynamic_sensor_meta.uuid,
635d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland                   dyn.uuid.data(),
636d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland                   sizeof(dst->dynamic_sensor_meta.uuid));
637d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        }
638d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    }
639d333511e94afbcc6462dd9c81405f4a3e30ecac9Steven Moreland}
640d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland
641d15c030f7255ec9db8567a4ee77a56844982586dSteven Morelandvoid SensorDevice::convertToSensorEvents(
642d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        const hidl_vec<Event> &src,
643d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        const hidl_vec<SensorInfo> &dynamicSensorsAdded,
644d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        sensors_event_t *dst) {
645d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    // Allocate a sensor_t structure for each dynamic sensor added and insert
646d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    // it into the dictionary of connected dynamic sensors keyed by handle.
647d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    for (size_t i = 0; i < dynamicSensorsAdded.size(); ++i) {
648d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        const SensorInfo &info = dynamicSensorsAdded[i];
649d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland
650d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        auto it = mConnectedDynamicSensors.find(info.sensorHandle);
651d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        CHECK(it == mConnectedDynamicSensors.end());
652d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland
653d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        sensor_t *sensor = new sensor_t;
654d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        convertToSensor(info, sensor);
655d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland
656d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        mConnectedDynamicSensors.insert(
657d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland                std::make_pair(sensor->handle, sensor));
658d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    }
659d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland
660d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    for (size_t i = 0; i < src.size(); ++i) {
661d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland        convertToSensorEvent(src[i], &dst[i]);
662d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland    }
663d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland}
664d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland
6653889e6ea1c321cbaf8a959775da58509672143afPeng Xuvoid SensorDevice::handleHidlDeath(const std::string & detail) {
6663889e6ea1c321cbaf8a959775da58509672143afPeng Xu    // restart is the only option at present.
6673889e6ea1c321cbaf8a959775da58509672143afPeng Xu    LOG_ALWAYS_FATAL("Abort due to ISensors hidl service failure, detail: %s.", detail.c_str());
6683889e6ea1c321cbaf8a959775da58509672143afPeng Xu}
6693889e6ea1c321cbaf8a959775da58509672143afPeng Xu
670f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian// ---------------------------------------------------------------------------
671f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}; // namespace android
672