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