• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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