• 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 
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