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
17f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#ifndef ANDROID_SENSOR_DEVICE_H
18f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#define ANDROID_SENSOR_DEVICE_H
19f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
206a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu#include "SensorServiceUtils.h"
21f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
22801ea093b0e923a61b832f2adba698a273479880Mathias Agopian#include <sensor/Sensor.h>
23d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland#include <stdint.h>
24d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland#include <sys/types.h>
25f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include <utils/KeyedVector.h>
26f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include <utils/Singleton.h>
27f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#include <utils/String8.h>
28f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
29e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu#include <string>
302bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu#include <unordered_map>
312bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu#include <algorithm> //std::max std::min
3299fdbb5fdc6a2ab4cc1fdf99872a3b30cbbc6f0eAndreas Huber
3399fdbb5fdc6a2ab4cc1fdf99872a3b30cbbc6f0eAndreas Huber#include "android/hardware/sensors/1.0/ISensors.h"
3499fdbb5fdc6a2ab4cc1fdf99872a3b30cbbc6f0eAndreas Huber
3596b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi#include "RingBuffer.h"
3696b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi
37f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian// ---------------------------------------------------------------------------
38f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
39f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopiannamespace android {
4099fdbb5fdc6a2ab4cc1fdf99872a3b30cbbc6f0eAndreas Huber
41f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian// ---------------------------------------------------------------------------
426a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xuusing SensorServiceUtil::Dumpable;
433889e6ea1c321cbaf8a959775da58509672143afPeng Xuusing hardware::Return;
44f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
456a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xuclass SensorDevice : public Singleton<SensorDevice>, public Dumpable {
466a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xupublic:
4796b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi
4896b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi    class HidlTransportErrorLog {
4996b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi     public:
5096b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi
5196b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi        HidlTransportErrorLog() {
5296b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi            mTs = 0;
5396b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi            mCount = 0;
5496b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi        }
5596b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi
5696b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi        HidlTransportErrorLog(time_t ts, int count) {
5796b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi            mTs = ts;
5896b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi            mCount = count;
5996b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi        }
6096b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi
6196b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi        String8 toString() const {
6296b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi            String8 result;
6396b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi            struct tm *timeInfo = localtime(&mTs);
6496b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi            result.appendFormat("%02d:%02d:%02d :: %d", timeInfo->tm_hour, timeInfo->tm_min,
6596b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi                                timeInfo->tm_sec, mCount);
6696b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi            return result;
6796b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi        }
6896b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi
6996b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi    private:
7096b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi        time_t mTs; // timestamp of the error
7196b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi        int mCount;   // number of transport errors observed
7296b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi    };
7396b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi
746a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    ssize_t getSensorList(sensor_t const** list);
7599fdbb5fdc6a2ab4cc1fdf99872a3b30cbbc6f0eAndreas Huber
766a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    void handleDynamicSensorConnection(int handle, bool connected);
776a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    status_t initCheck() const;
786a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    int getHalDeviceVersion() const;
7999fdbb5fdc6a2ab4cc1fdf99872a3b30cbbc6f0eAndreas Huber
806a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    ssize_t poll(sensors_event_t* buffer, size_t count);
8199fdbb5fdc6a2ab4cc1fdf99872a3b30cbbc6f0eAndreas Huber
826a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    status_t activate(void* ident, int handle, int enabled);
836a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    status_t batch(void* ident, int handle, int flags, int64_t samplingPeriodNs,
846a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu                   int64_t maxBatchReportLatencyNs);
856a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    // Call batch with timeout zero instead of calling setDelay() for newer devices.
866a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    status_t setDelay(void* ident, int handle, int64_t ns);
876a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    status_t flush(void* ident, int handle);
886a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    status_t setMode(uint32_t mode);
89e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu
905363254ba38b50da95e5bdb15391c139c182627cPeng Xu    bool isDirectReportSupported() const;
91e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    int32_t registerDirectChannel(const sensors_direct_mem_t *memory);
92e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    void unregisterDirectChannel(int32_t channelHandle);
93e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu    int32_t configureDirectChannel(int32_t sensorHandle,
94e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu            int32_t channelHandle, const struct sensors_direct_cfg_t *config);
95e36e34731cbe77a49aa5e7d687dde041d83d0370Peng Xu
966a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    void disableAllSensors();
976a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    void enableAllSensors();
986a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    void autoDisable(void *ident, int handle);
9999fdbb5fdc6a2ab4cc1fdf99872a3b30cbbc6f0eAndreas Huber
1006a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    status_t injectSensorData(const sensors_event_t *event);
1014f707f8b3da68d3055db895da9ae5216cc4f483aPeng Xu    void notifyConnectionDestroyed(void *ident);
1026a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu
1036a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    // Dumpable
1046a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xu    virtual std::string dump() const;
1056a2d3a06caa337857cf60cfc70a9a78909ad3608Peng Xuprivate:
106f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    friend class Singleton<SensorDevice>;
107d15c030f7255ec9db8567a4ee77a56844982586dSteven Moreland
10899fdbb5fdc6a2ab4cc1fdf99872a3b30cbbc6f0eAndreas Huber    sp<android::hardware::sensors::V1_0::ISensors> mSensors;
10999fdbb5fdc6a2ab4cc1fdf99872a3b30cbbc6f0eAndreas Huber    Vector<sensor_t> mSensorList;
1102bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu    std::unordered_map<int32_t, sensor_t*> mConnectedDynamicSensors;
11199fdbb5fdc6a2ab4cc1fdf99872a3b30cbbc6f0eAndreas Huber
112724d91d778e71c8186399f4955de14b54812b3edAravind Akella    static const nsecs_t MINIMUM_EVENTS_PERIOD =   1000000; // 1000 Hz
113724d91d778e71c8186399f4955de14b54812b3edAravind Akella    mutable Mutex mLock; // protect mActivationCount[].batchParams
114f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    // fixed-size array after construction
115724d91d778e71c8186399f4955de14b54812b3edAravind Akella
116724d91d778e71c8186399f4955de14b54812b3edAravind Akella    // Struct to store all the parameters(samplingPeriod, maxBatchReportLatency and flags) from
117724d91d778e71c8186399f4955de14b54812b3edAravind Akella    // batch call. For continous mode clients, maxBatchReportLatency is set to zero.
118724d91d778e71c8186399f4955de14b54812b3edAravind Akella    struct BatchParams {
1192bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu      nsecs_t mTSample, mTBatch;
1202bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu      BatchParams() : mTSample(INT64_MAX), mTBatch(INT64_MAX) {}
1212bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu      BatchParams(nsecs_t tSample, nsecs_t tBatch): mTSample(tSample), mTBatch(tBatch) {}
122724d91d778e71c8186399f4955de14b54812b3edAravind Akella      bool operator != (const BatchParams& other) {
1232bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu          return !(mTSample == other.mTSample && mTBatch == other.mTBatch);
1242bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu      }
1252bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu      // Merge another parameter with this one. The updated mTSample will be the min of the two.
1262bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu      // The update mTBatch will be the min of original mTBatch and the apparent batch period
1272bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu      // of the other. the apparent batch is the maximum of mTBatch and mTSample,
1282bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu      void merge(const BatchParams &other) {
1292bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu          mTSample = std::min(mTSample, other.mTSample);
1302bec6230661e66ce37d8a074df32e07553e3cb8cPeng Xu          mTBatch = std::min(mTBatch, std::max(other.mTBatch, other.mTSample));
131724d91d778e71c8186399f4955de14b54812b3edAravind Akella      }
132724d91d778e71c8186399f4955de14b54812b3edAravind Akella    };
133724d91d778e71c8186399f4955de14b54812b3edAravind Akella
134724d91d778e71c8186399f4955de14b54812b3edAravind Akella    // Store batch parameters in the KeyedVector and the optimal batch_rate and timeout in
135724d91d778e71c8186399f4955de14b54812b3edAravind Akella    // bestBatchParams. For every batch() call corresponding params are stored in batchParams
136724d91d778e71c8186399f4955de14b54812b3edAravind Akella    // vector. A continuous mode request is batch(... timeout=0 ..) followed by activate(). A batch
137724d91d778e71c8186399f4955de14b54812b3edAravind Akella    // mode request is batch(... timeout > 0 ...) followed by activate().
138724d91d778e71c8186399f4955de14b54812b3edAravind Akella    // Info is a per-sensor data structure which contains the batch parameters for each client that
139724d91d778e71c8186399f4955de14b54812b3edAravind Akella    // has registered for this sensor.
140f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    struct Info {
141724d91d778e71c8186399f4955de14b54812b3edAravind Akella        BatchParams bestBatchParams;
142724d91d778e71c8186399f4955de14b54812b3edAravind Akella        // Key is the unique identifier(ident) for each client, value is the batch parameters
143724d91d778e71c8186399f4955de14b54812b3edAravind Akella        // requested by the client.
144724d91d778e71c8186399f4955de14b54812b3edAravind Akella        KeyedVector<void*, BatchParams> batchParams;
145724d91d778e71c8186399f4955de14b54812b3edAravind Akella
146724d91d778e71c8186399f4955de14b54812b3edAravind Akella        // Sets batch parameters for this ident. Returns error if this ident is not already present
147724d91d778e71c8186399f4955de14b54812b3edAravind Akella        // in the KeyedVector above.
148724d91d778e71c8186399f4955de14b54812b3edAravind Akella        status_t setBatchParamsForIdent(void* ident, int flags, int64_t samplingPeriodNs,
149724d91d778e71c8186399f4955de14b54812b3edAravind Akella                                        int64_t maxBatchReportLatencyNs);
150724d91d778e71c8186399f4955de14b54812b3edAravind Akella        // Finds the optimal parameters for batching and stores them in bestBatchParams variable.
151724d91d778e71c8186399f4955de14b54812b3edAravind Akella        void selectBatchParams();
152724d91d778e71c8186399f4955de14b54812b3edAravind Akella        // Removes batchParams for an ident and re-computes bestBatchParams. Returns the index of
153724d91d778e71c8186399f4955de14b54812b3edAravind Akella        // the removed ident. If index >=0, ident is present and successfully removed.
154724d91d778e71c8186399f4955de14b54812b3edAravind Akella        ssize_t removeBatchParamsForIdent(void* ident);
1554949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
1564949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella        int numActiveClients();
157f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    };
158f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    DefaultKeyedVector<int, Info> mActivationCount;
159f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
16096b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi    // Keep track of any hidl transport failures
16196b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi    SensorServiceUtil::RingBuffer<HidlTransportErrorLog> mHidlTransportErrors;
16296b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi    int mTotalHidlTransportErrors;
16396b12d8dedd6bffdc520920d731c5dff82e122dfAshutosh Joshi
1644949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    // Use this vector to determine which client is activated or deactivated.
1654949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    SortedVector<void *> mDisabledClients;
166f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian    SensorDevice();
167a8fad9bd6ca694bb0f86d617c72122d2220ec253Peng Xu    bool connectHidlService();
1684949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella
1693889e6ea1c321cbaf8a959775da58509672143afPeng Xu    static void handleHidlDeath(const std::string &detail);
1703889e6ea1c321cbaf8a959775da58509672143afPeng Xu    template<typename T>
1713889e6ea1c321cbaf8a959775da58509672143afPeng Xu    static Return<T> checkReturn(Return<T> &&ret) {
1723889e6ea1c321cbaf8a959775da58509672143afPeng Xu        if (!ret.isOk()) {
1733889e6ea1c321cbaf8a959775da58509672143afPeng Xu            handleHidlDeath(ret.description());
1743889e6ea1c321cbaf8a959775da58509672143afPeng Xu        }
1753889e6ea1c321cbaf8a959775da58509672143afPeng Xu        return std::move(ret);
1763889e6ea1c321cbaf8a959775da58509672143afPeng Xu    }
1773889e6ea1c321cbaf8a959775da58509672143afPeng Xu
1784949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    bool isClientDisabled(void* ident);
1794949c50372de4c7fdb57de1dc0c1f5bb3ac463ebAravind Akella    bool isClientDisabledLocked(void* ident);
18099fdbb5fdc6a2ab4cc1fdf99872a3b30cbbc6f0eAndreas Huber
18199fdbb5fdc6a2ab4cc1fdf99872a3b30cbbc6f0eAndreas Huber    using Event = hardware::sensors::V1_0::Event;
18299fdbb5fdc6a2ab4cc1fdf99872a3b30cbbc6f0eAndreas Huber    using SensorInfo = hardware::sensors::V1_0::SensorInfo;
18399fdbb5fdc6a2ab4cc1fdf99872a3b30cbbc6f0eAndreas Huber
18499fdbb5fdc6a2ab4cc1fdf99872a3b30cbbc6f0eAndreas Huber    void convertToSensorEvent(const Event &src, sensors_event_t *dst);
18599fdbb5fdc6a2ab4cc1fdf99872a3b30cbbc6f0eAndreas Huber
18699fdbb5fdc6a2ab4cc1fdf99872a3b30cbbc6f0eAndreas Huber    void convertToSensorEvents(
18799fdbb5fdc6a2ab4cc1fdf99872a3b30cbbc6f0eAndreas Huber            const hardware::hidl_vec<Event> &src,
18899fdbb5fdc6a2ab4cc1fdf99872a3b30cbbc6f0eAndreas Huber            const hardware::hidl_vec<SensorInfo> &dynamicSensorsAdded,
18999fdbb5fdc6a2ab4cc1fdf99872a3b30cbbc6f0eAndreas Huber            sensors_event_t *dst);
1905363254ba38b50da95e5bdb15391c139c182627cPeng Xu
1915363254ba38b50da95e5bdb15391c139c182627cPeng Xu    bool mIsDirectReportSupported;
192f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian};
193f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
194f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian// ---------------------------------------------------------------------------
195f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian}; // namespace android
196f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian
197f001c92436b4a66eb7687286325ced7f10c9f917Mathias Agopian#endif // ANDROID_SENSOR_DEVICE_H
198