1 /*
2 * Copyright (C) 2017 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 #include "BaseDynamicSensorDaemon.h"
18 #include "BaseSensorObject.h"
19 #include "DummyDynamicAccelDaemon.h"
20 #include "HidRawSensorDaemon.h"
21 #include "DynamicSensorManager.h"
22
23 #include <utils/Log.h>
24 #include <utils/SystemClock.h>
25 #include <cutils/properties.h>
26
27 #include <cassert>
28
29 namespace android {
30 namespace SensorHalExt {
31
createInstance(int handleBase,int handleCount,SensorEventCallback * callback)32 DynamicSensorManager* DynamicSensorManager::createInstance(
33 int handleBase, int handleCount, SensorEventCallback *callback) {
34 auto m = new DynamicSensorManager(handleBase, handleBase + handleCount - 1, callback);
35 m->mDaemonVector.push_back(new DummyDynamicAccelDaemon(*m));
36 m->mDaemonVector.push_back(new HidRawSensorDaemon(*m));
37 return m;
38 }
39
DynamicSensorManager(int handleBase,int handleMax,SensorEventCallback * callback)40 DynamicSensorManager::DynamicSensorManager(
41 int handleBase, int handleMax, SensorEventCallback* callback) :
42 mHandleRange(handleBase, handleMax),
43 mCallback(callback),
44 mFifo(callback ? 0 : kFifoSize),
45 mNextHandle(handleBase+1),
46 kSensorOpTimeout(
47 std::chrono::milliseconds((uint32_t)property_get_int32(
48 "vendor.sensors.dynamic_sensor_op_timeout_ms", 1600))) {
49 assert(handleBase > 0 && handleMax > handleBase + 1); // handleBase is reserved
50
51 mMetaSensor = (const sensor_t) {
52 "Dynamic Sensor Manager",
53 "Google",
54 1, // version
55 handleBase, // handle
56 SENSOR_TYPE_DYNAMIC_SENSOR_META,
57 1, // maxRange
58 1, // resolution
59 1e-6f, // power, very small number instead of 0
60 // to avoid sigularity in app
61 (int32_t)(1000), // minDelay
62 0, // fifoReservedEventCount
63 0, // fifoMaxEventCount
64 SENSOR_STRING_TYPE_DYNAMIC_SENSOR_META,
65 "", // requiredPermission
66 (long)(1000), // maxDelay
67 SENSOR_FLAG_SPECIAL_REPORTING_MODE | SENSOR_FLAG_WAKE_UP,
68 { NULL, NULL }
69 };
70 }
71
~DynamicSensorManager()72 DynamicSensorManager::~DynamicSensorManager() {
73 // free all daemons first
74 mDaemonVector.clear();
75 }
76
owns(int handle) const77 bool DynamicSensorManager::owns(int handle) const {
78 return handle >= mHandleRange.first && handle < mHandleRange.second;
79 }
80
activate(int handle,bool enable)81 int DynamicSensorManager::activate(int handle, bool enable) {
82 if (handle == mHandleRange.first) {
83 mMetaSensorActive = enable;
84 return 0;
85 }
86
87 // in case there is a pending report, now it is time to remove it as it is no longer necessary.
88 {
89 std::lock_guard<std::mutex> lk(mLock);
90 mPendingReport.erase(handle);
91 }
92
93 return operateSensor(handle,
94 [=] (sp<BaseSensorObject> s)->int {
95 return s->enable(enable);
96 });
97 }
98
batch(int handle,nsecs_t sample_period,nsecs_t batch_period)99 int DynamicSensorManager::batch(int handle, nsecs_t sample_period, nsecs_t batch_period) {
100 if (handle == mHandleRange.first) {
101 // ignored
102 return 0;
103 }
104 return operateSensor(handle,
105 [=] (sp<BaseSensorObject> s)->int {
106 return s->batch(sample_period, batch_period);
107 });
108 }
109
setDelay(int handle,nsecs_t sample_period)110 int DynamicSensorManager::setDelay(int handle, nsecs_t sample_period) {
111 return batch(handle, sample_period, 0);
112 }
113
flush(int handle)114 int DynamicSensorManager::flush(int handle) {
115 if (handle == mHandleRange.first) {
116 if (mMetaSensorActive) {
117 static const sensors_event_t event = {
118 .sensor = mHandleRange.first,
119 .type = SENSOR_TYPE_META_DATA,
120 .meta_data.what = META_DATA_FLUSH_COMPLETE,
121 .timestamp = TIMESTAMP_AUTO_FILL, // timestamp will be filled at dispatcher
122 };
123 submitEvent(nullptr, event);
124 } else {
125 return -EINVAL;
126 }
127 return 0;
128 }
129 return operateSensor(handle, [] (sp<BaseSensorObject> s)->int {return s->flush();});
130 }
131
poll(sensors_event_t * data,int count)132 int DynamicSensorManager::poll(sensors_event_t * data, int count) {
133 assert(mCallback == nullptr);
134 std::lock_guard<std::mutex> lk(mFifoLock);
135 return mFifo.read(data, count);
136 }
137
registerSensor(sp<BaseSensorObject> sensor)138 bool DynamicSensorManager::registerSensor(sp<BaseSensorObject> sensor) {
139 std::lock_guard<std::mutex> lk(mLock);
140 if (mReverseMap.find(sensor.get()) != mReverseMap.end()) {
141 ALOGE("trying to add the same sensor twice, ignore");
142 return false;
143 }
144 int handle = getNextAvailableHandle();
145 if (handle < 0) {
146 ALOGE("Running out of handle, quit.");
147 return false;
148 }
149
150 // these emplace will always be successful
151 mMap.emplace(handle, sensor);
152 mReverseMap.emplace(sensor.get(), handle);
153 sensor->setEventCallback(this);
154
155 auto entry = mPendingReport.emplace(
156 std::piecewise_construct,
157 std::forward_as_tuple(handle),
158 std::forward_as_tuple(handle, sensor));
159 if (entry.second) {
160 submitEvent(nullptr, entry.first->second.generateConnectionEvent(mHandleRange.first));
161 }
162 return entry.second;
163 }
164
unregisterSensor(sp<BaseSensorObject> sensor)165 void DynamicSensorManager::unregisterSensor(sp<BaseSensorObject> sensor) {
166 std::lock_guard<std::mutex> lk(mLock);
167 auto i = mReverseMap.find(sensor.get());
168 if (i == mReverseMap.end()) {
169 ALOGE("cannot remove a non-exist sensor");
170 return;
171 }
172 int handle = i->second;
173 mReverseMap.erase(i);
174 mMap.erase(handle);
175
176 // will not clean up mPendingReport here, it will be cleaned up when at first activate call.
177 // sensorservice is guranteed to call activate upon arrival of dynamic sensor meta connection
178 // event.
179
180 // send disconnection event
181 sensors_event_t event;
182 ConnectionReport::fillDisconnectionEvent(&event, mHandleRange.first, handle);
183 submitEvent(nullptr, event);
184 }
185
submitEvent(sp<BaseSensorObject> source,const sensors_event_t & e)186 int DynamicSensorManager::submitEvent(sp<BaseSensorObject> source, const sensors_event_t &e) {
187 int handle;
188 if (source == nullptr) {
189 handle = mHandleRange.first;
190 } else {
191 std::lock_guard<std::mutex> lk(mLock);
192 auto i = mReverseMap.find(source.get());
193 if (i == mReverseMap.end()) {
194 ALOGE("cannot submit event for sensor that has not been registered");
195 return NAME_NOT_FOUND;
196 }
197 handle = i->second;
198 }
199
200 // making a copy of events, prepare for editing
201 sensors_event_t event = e;
202 event.version = sizeof(event);
203
204 // special case of flush complete
205 if (event.type == SENSOR_TYPE_META_DATA) {
206 event.sensor = 0;
207 event.meta_data.sensor = handle;
208 } else {
209 event.sensor = handle;
210 }
211
212 // set timestamp if it is default value
213 if (event.timestamp == TIMESTAMP_AUTO_FILL) {
214 event.timestamp = elapsedRealtimeNano();
215 }
216
217 if (mCallback) {
218 // extention mode, calling callback directly
219 int ret;
220
221 ret = mCallback->submitEvent(nullptr, event);
222 if (ret < 0) {
223 ALOGE("DynamicSensorManager callback failed, ret: %d", ret);
224 }
225 } else {
226 // standalone mode, add event to internal buffer for poll() to pick up
227 std::lock_guard<std::mutex> lk(mFifoLock);
228 if (mFifo.write(&event, 1) < 0) {
229 ALOGE("DynamicSensorManager fifo full");
230 }
231 }
232 return 0;
233 }
234
getNextAvailableHandle()235 int DynamicSensorManager::getNextAvailableHandle() {
236 if (mNextHandle == mHandleRange.second) {
237 return -1;
238 }
239 return mNextHandle++;
240 }
241
getDynamicMetaSensor() const242 const sensor_t& DynamicSensorManager::getDynamicMetaSensor() const {
243 return mMetaSensor;
244 }
245
operateSensor(int handle,OperateSensorFunc sensorFunc)246 int DynamicSensorManager::operateSensor(
247 int handle, OperateSensorFunc sensorFunc) {
248 std::shared_future<int> sensorOp;
249 {
250 std::lock_guard<std::mutex> lock(mSensorOpQueueLock);
251
252 // Invoke the function asynchronously.
253 sensorOp = std::async(
254 [this, handle = handle, sensorFunc = sensorFunc,
255 sensorOpIndex = mNextSensorOpIndex] ()->int {
256 return operateSensor(handle, sensorFunc, sensorOpIndex);
257 }).share();
258
259 // Add sensor operation to the queue.
260 mSensorOpQueue.push({mNextSensorOpIndex, sensorOp});
261 mNextSensorOpIndex++;
262 }
263
264 // Wait for the sensor operation to complete.
265 if (sensorOp.wait_for(kSensorOpTimeout) != std::future_status::ready) {
266 ALOGE("sensor operation timed out");
267 return TIMED_OUT;
268 }
269
270 return sensorOp.get();
271 }
272
operateSensor(int handle,OperateSensorFunc sensorFunc,uint64_t sensorOpIndex)273 int DynamicSensorManager::operateSensor(
274 int handle, OperateSensorFunc sensorFunc, uint64_t sensorOpIndex) {
275 int rv = 0;
276
277 // Wait until this sensor operation is at the head of the queue.
278 while (1) {
279 std::shared_future<int> headSensorOp;
280
281 {
282 std::lock_guard<std::mutex> lock(mSensorOpQueueLock);
283
284 if (mSensorOpQueue.front().first == sensorOpIndex) {
285 break;
286 }
287 headSensorOp = mSensorOpQueue.front().second;
288 }
289 headSensorOp.wait();
290 }
291
292 // Perform sensor operation.
293 sp<BaseSensorObject> sensor;
294 {
295 std::lock_guard<std::mutex> lk(mLock);
296 const auto i = mMap.find(handle);
297 if (i == mMap.end()) {
298 rv = BAD_VALUE;
299 }
300 if (rv == 0) {
301 sensor = i->second.promote();
302 if (sensor == nullptr) {
303 // sensor object is already gone
304 rv = BAD_VALUE;
305 }
306 }
307 }
308 if (rv == 0) {
309 rv = sensorFunc(sensor);
310 }
311
312 // Remove sensor operation from queue. When the operation's shared state is
313 // destroyed, execution of this function ceases. Thus, if the state is
314 // destroyed when the operation is removed from the queue, the lock will
315 // never be released. To prevent that, the state is shared locally, so it
316 // isn't destroyed until this function completes.
317 std::shared_future<int> sensorOp;
318 {
319 std::lock_guard<std::mutex> lock(mSensorOpQueueLock);
320 sensorOp = mSensorOpQueue.front().second;
321 mSensorOpQueue.pop();
322 }
323
324 return rv;
325 }
326
ConnectionReport(int handle,sp<BaseSensorObject> sensor)327 DynamicSensorManager::ConnectionReport::ConnectionReport(
328 int handle, sp<BaseSensorObject> sensor) :
329 mSensor(*(sensor->getSensor())),
330 mName(mSensor.name),
331 mVendor(mSensor.vendor),
332 mPermission(mSensor.requiredPermission),
333 mStringType(mSensor.stringType),
334 mGenerated(false) {
335 mSensor.name = mName.c_str();
336 mSensor.vendor = mVendor.c_str();
337 mSensor.requiredPermission = mPermission.c_str();
338 mSensor.stringType = mStringType.c_str();
339 mSensor.handle = handle;
340 memset(&mEvent, 0, sizeof(mEvent));
341 mEvent.version = sizeof(mEvent);
342 sensor->getUuid(mUuid);
343 ALOGV("Connection report init: name = %s, handle = %d", mSensor.name, mSensor.handle);
344 }
345
~ConnectionReport()346 DynamicSensorManager::ConnectionReport::~ConnectionReport() {
347 ALOGV("Connection report dtor: name = %s, handle = %d", mSensor.name, mSensor.handle);
348 }
349
350 const sensors_event_t& DynamicSensorManager::ConnectionReport::
generateConnectionEvent(int metaHandle)351 generateConnectionEvent(int metaHandle) {
352 if (!mGenerated) {
353 mEvent.sensor = metaHandle;
354 mEvent.type = SENSOR_TYPE_DYNAMIC_SENSOR_META;
355 mEvent.timestamp = elapsedRealtimeNano();
356 mEvent.dynamic_sensor_meta =
357 (dynamic_sensor_meta_event_t) {true, mSensor.handle, &mSensor, {0}};
358 memcpy(&mEvent.dynamic_sensor_meta.uuid, &mUuid, sizeof(mEvent.dynamic_sensor_meta.uuid));
359 mGenerated = true;
360 }
361 return mEvent;
362 }
363
364 void DynamicSensorManager::ConnectionReport::
fillDisconnectionEvent(sensors_event_t * event,int metaHandle,int handle)365 fillDisconnectionEvent(sensors_event_t* event, int metaHandle, int handle) {
366 memset(event, 0, sizeof(sensors_event_t));
367 event->version = sizeof(sensors_event_t);
368 event->sensor = metaHandle;
369 event->type = SENSOR_TYPE_DYNAMIC_SENSOR_META;
370 event->timestamp = elapsedRealtimeNano();
371 event->dynamic_sensor_meta.connected = false;
372 event->dynamic_sensor_meta.handle = handle;
373 }
374
375 } // namespace SensorHalExt
376 } // namespace android
377