1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ANDROID_SENSOR_DEVICE_H
18 #define ANDROID_SENSOR_DEVICE_H
19 
20 #include "SensorDeviceUtils.h"
21 #include "SensorServiceUtils.h"
22 
23 #include <sensor/Sensor.h>
24 #include <stdint.h>
25 #include <sys/types.h>
26 #include <utils/KeyedVector.h>
27 #include <utils/Singleton.h>
28 #include <utils/String8.h>
29 
30 #include <string>
31 #include <unordered_map>
32 #include <algorithm> //std::max std::min
33 
34 #include "android/hardware/sensors/1.0/ISensors.h"
35 
36 #include "RingBuffer.h"
37 
38 // ---------------------------------------------------------------------------
39 
40 namespace android {
41 
42 // ---------------------------------------------------------------------------
43 
44 class SensorDevice : public Singleton<SensorDevice>, public SensorServiceUtil::Dumpable {
45 public:
46     class HidlTransportErrorLog {
47      public:
48 
HidlTransportErrorLog()49         HidlTransportErrorLog() {
50             mTs = 0;
51             mCount = 0;
52         }
53 
HidlTransportErrorLog(time_t ts,int count)54         HidlTransportErrorLog(time_t ts, int count) {
55             mTs = ts;
56             mCount = count;
57         }
58 
toString()59         String8 toString() const {
60             String8 result;
61             struct tm *timeInfo = localtime(&mTs);
62             result.appendFormat("%02d:%02d:%02d :: %d", timeInfo->tm_hour, timeInfo->tm_min,
63                                 timeInfo->tm_sec, mCount);
64             return result;
65         }
66 
67     private:
68         time_t mTs; // timestamp of the error
69         int mCount;   // number of transport errors observed
70     };
71 
72     ssize_t getSensorList(sensor_t const** list);
73 
74     void handleDynamicSensorConnection(int handle, bool connected);
75     status_t initCheck() const;
76     int getHalDeviceVersion() const;
77 
78     ssize_t poll(sensors_event_t* buffer, size_t count);
79 
80     status_t activate(void* ident, int handle, int enabled);
81     status_t batch(void* ident, int handle, int flags, int64_t samplingPeriodNs,
82                    int64_t maxBatchReportLatencyNs);
83     // Call batch with timeout zero instead of calling setDelay() for newer devices.
84     status_t setDelay(void* ident, int handle, int64_t ns);
85     status_t flush(void* ident, int handle);
86     status_t setMode(uint32_t mode);
87 
88     bool isDirectReportSupported() const;
89     int32_t registerDirectChannel(const sensors_direct_mem_t *memory);
90     void unregisterDirectChannel(int32_t channelHandle);
91     int32_t configureDirectChannel(int32_t sensorHandle,
92             int32_t channelHandle, const struct sensors_direct_cfg_t *config);
93 
94     void disableAllSensors();
95     void enableAllSensors();
96     void autoDisable(void *ident, int handle);
97 
98     status_t injectSensorData(const sensors_event_t *event);
99     void notifyConnectionDestroyed(void *ident);
100 
101     // Dumpable
102     virtual std::string dump() const;
103 private:
104     friend class Singleton<SensorDevice>;
105 
106     sp<hardware::sensors::V1_0::ISensors> mSensors;
107     Vector<sensor_t> mSensorList;
108     std::unordered_map<int32_t, sensor_t*> mConnectedDynamicSensors;
109 
110     static const nsecs_t MINIMUM_EVENTS_PERIOD =   1000000; // 1000 Hz
111     mutable Mutex mLock; // protect mActivationCount[].batchParams
112     // fixed-size array after construction
113 
114     // Struct to store all the parameters(samplingPeriod, maxBatchReportLatency and flags) from
115     // batch call. For continous mode clients, maxBatchReportLatency is set to zero.
116     struct BatchParams {
117       nsecs_t mTSample, mTBatch;
BatchParamsBatchParams118       BatchParams() : mTSample(INT64_MAX), mTBatch(INT64_MAX) {}
BatchParamsBatchParams119       BatchParams(nsecs_t tSample, nsecs_t tBatch): mTSample(tSample), mTBatch(tBatch) {}
120       bool operator != (const BatchParams& other) {
121           return !(mTSample == other.mTSample && mTBatch == other.mTBatch);
122       }
123       // Merge another parameter with this one. The updated mTSample will be the min of the two.
124       // The update mTBatch will be the min of original mTBatch and the apparent batch period
125       // of the other. the apparent batch is the maximum of mTBatch and mTSample,
mergeBatchParams126       void merge(const BatchParams &other) {
127           mTSample = std::min(mTSample, other.mTSample);
128           mTBatch = std::min(mTBatch, std::max(other.mTBatch, other.mTSample));
129       }
130     };
131 
132     // Store batch parameters in the KeyedVector and the optimal batch_rate and timeout in
133     // bestBatchParams. For every batch() call corresponding params are stored in batchParams
134     // vector. A continuous mode request is batch(... timeout=0 ..) followed by activate(). A batch
135     // mode request is batch(... timeout > 0 ...) followed by activate().
136     // Info is a per-sensor data structure which contains the batch parameters for each client that
137     // has registered for this sensor.
138     struct Info {
139         BatchParams bestBatchParams;
140         // Key is the unique identifier(ident) for each client, value is the batch parameters
141         // requested by the client.
142         KeyedVector<void*, BatchParams> batchParams;
143 
144         // Sets batch parameters for this ident. Returns error if this ident is not already present
145         // in the KeyedVector above.
146         status_t setBatchParamsForIdent(void* ident, int flags, int64_t samplingPeriodNs,
147                                         int64_t maxBatchReportLatencyNs);
148         // Finds the optimal parameters for batching and stores them in bestBatchParams variable.
149         void selectBatchParams();
150         // Removes batchParams for an ident and re-computes bestBatchParams. Returns the index of
151         // the removed ident. If index >=0, ident is present and successfully removed.
152         ssize_t removeBatchParamsForIdent(void* ident);
153 
154         int numActiveClients();
155     };
156     DefaultKeyedVector<int, Info> mActivationCount;
157 
158     // Keep track of any hidl transport failures
159     SensorServiceUtil::RingBuffer<HidlTransportErrorLog> mHidlTransportErrors;
160     int mTotalHidlTransportErrors;
161 
162     // Use this vector to determine which client is activated or deactivated.
163     SortedVector<void *> mDisabledClients;
164     SensorDevice();
165     bool connectHidlService();
166 
167     static void handleHidlDeath(const std::string &detail);
168     template<typename T>
checkReturn(Return<T> && ret)169     static Return<T> checkReturn(Return<T> &&ret) {
170         if (!ret.isOk()) {
171             handleHidlDeath(ret.description());
172         }
173         return std::move(ret);
174     }
175     //TODO(b/67425500): remove waiter after bug is resolved.
176     sp<SensorDeviceUtils::HidlServiceRegistrationWaiter> mRestartWaiter;
177 
178     bool isClientDisabled(void* ident);
179     bool isClientDisabledLocked(void* ident);
180 
181     using Event = hardware::sensors::V1_0::Event;
182     using SensorInfo = hardware::sensors::V1_0::SensorInfo;
183 
184     void convertToSensorEvent(const Event &src, sensors_event_t *dst);
185 
186     void convertToSensorEvents(
187             const hardware::hidl_vec<Event> &src,
188             const hardware::hidl_vec<SensorInfo> &dynamicSensorsAdded,
189             sensors_event_t *dst);
190 
191     bool mIsDirectReportSupported;
192 };
193 
194 // ---------------------------------------------------------------------------
195 }; // namespace android
196 
197 #endif // ANDROID_SENSOR_DEVICE_H
198