• Home
  • History
  • Annotate
  • 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          // ignored
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              [&enable] (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              [&sample_period, &batch_period] (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          // submit a flush complete here
113          static const sensors_event_t event = {
114              .type = SENSOR_TYPE_META_DATA,
115              .sensor = mHandleRange.first,
116              .timestamp = TIMESTAMP_AUTO_FILL,  // timestamp will be filled at dispatcher
117          };
118          submitEvent(nullptr, event);
119          return 0;
120      }
121      return operateSensor(handle, [] (sp<BaseSensorObject> s)->int {return s->flush();});
122  }
123  
poll(sensors_event_t * data,int count)124  int DynamicSensorManager::poll(sensors_event_t * data, int count) {
125      assert(mCallback == nullptr);
126      std::lock_guard<std::mutex> lk(mFifoLock);
127      return mFifo.read(data, count);
128  }
129  
registerSensor(sp<BaseSensorObject> sensor)130  bool DynamicSensorManager::registerSensor(sp<BaseSensorObject> sensor) {
131      std::lock_guard<std::mutex> lk(mLock);
132      if (mReverseMap.find(sensor.get()) != mReverseMap.end()) {
133          ALOGE("trying to add the same sensor twice, ignore");
134          return false;
135      }
136      int handle = getNextAvailableHandle();
137      if (handle < 0) {
138          ALOGE("Running out of handle, quit.");
139          return false;
140      }
141  
142      // these emplace will always be successful
143      mMap.emplace(handle, sensor);
144      mReverseMap.emplace(sensor.get(), handle);
145      sensor->setEventCallback(this);
146  
147      auto entry = mPendingReport.emplace(
148              std::piecewise_construct,
149              std::forward_as_tuple(handle),
150              std::forward_as_tuple(handle, sensor));
151      if (entry.second) {
152          submitEvent(nullptr, entry.first->second.generateConnectionEvent(mHandleRange.first));
153      }
154      return entry.second;
155  }
156  
unregisterSensor(sp<BaseSensorObject> sensor)157  void DynamicSensorManager::unregisterSensor(sp<BaseSensorObject> sensor) {
158      std::lock_guard<std::mutex> lk(mLock);
159      auto i = mReverseMap.find(sensor.get());
160      if (i == mReverseMap.end()) {
161          ALOGE("cannot remove a non-exist sensor");
162          return;
163      }
164      int handle = i->second;
165      mReverseMap.erase(i);
166      mMap.erase(handle);
167  
168      // will not clean up mPendingReport here, it will be cleaned up when at first activate call.
169      // sensorservice is guranteed to call activate upon arrival of dynamic sensor meta connection
170      // event.
171  
172      // send disconnection event
173      sensors_event_t event;
174      ConnectionReport::fillDisconnectionEvent(&event, mHandleRange.first, handle);
175      submitEvent(nullptr, event);
176  }
177  
submitEvent(sp<BaseSensorObject> source,const sensors_event_t & e)178  int DynamicSensorManager::submitEvent(sp<BaseSensorObject> source, const sensors_event_t &e) {
179      int handle;
180      if (source == nullptr) {
181          handle = mHandleRange.first;
182      } else {
183          std::lock_guard<std::mutex> lk(mLock);
184          auto i = mReverseMap.find(source.get());
185          if (i == mReverseMap.end()) {
186              ALOGE("cannot submit event for sensor that has not been registered");
187              return NAME_NOT_FOUND;
188          }
189          handle = i->second;
190      }
191  
192      // making a copy of events, prepare for editing
193      sensors_event_t event = e;
194      event.version = sizeof(event);
195  
196      // special case of flush complete
197      if (event.type == SENSOR_TYPE_META_DATA) {
198          event.sensor = 0;
199          event.meta_data.sensor = handle;
200      } else {
201          event.sensor = handle;
202      }
203  
204      // set timestamp if it is default value
205      if (event.timestamp == TIMESTAMP_AUTO_FILL) {
206          event.timestamp = elapsedRealtimeNano();
207      }
208  
209      if (mCallback) {
210          // extention mode, calling callback directly
211          int ret;
212  
213          ret = mCallback->submitEvent(nullptr, event);
214          if (ret < 0) {
215              ALOGE("DynamicSensorManager callback failed, ret: %d", ret);
216          }
217      } else {
218          // standalone mode, add event to internal buffer for poll() to pick up
219          std::lock_guard<std::mutex> lk(mFifoLock);
220          if (mFifo.write(&event, 1) < 0) {
221              ALOGE("DynamicSensorManager fifo full");
222          }
223      }
224      return 0;
225  }
226  
getNextAvailableHandle()227  int DynamicSensorManager::getNextAvailableHandle() {
228      if (mNextHandle == mHandleRange.second) {
229          return -1;
230      }
231      return mNextHandle++;
232  }
233  
getDynamicMetaSensor() const234  const sensor_t& DynamicSensorManager::getDynamicMetaSensor() const {
235      return mMetaSensor;
236  }
237  
ConnectionReport(int handle,sp<BaseSensorObject> sensor)238  DynamicSensorManager::ConnectionReport::ConnectionReport(
239          int handle, sp<BaseSensorObject> sensor) :
240          mSensor(*(sensor->getSensor())),
241          mName(mSensor.name),
242          mVendor(mSensor.vendor),
243          mPermission(mSensor.requiredPermission),
244          mStringType(mSensor.stringType),
245          mGenerated(false) {
246      mSensor.name = mName.c_str();
247      mSensor.vendor = mVendor.c_str();
248      mSensor.requiredPermission = mPermission.c_str();
249      mSensor.stringType = mStringType.c_str();
250      mSensor.handle = handle;
251      memset(&mEvent, 0, sizeof(mEvent));
252      mEvent.version = sizeof(mEvent);
253      sensor->getUuid(mUuid);
254      ALOGV("Connection report init: name = %s, handle = %d", mSensor.name, mSensor.handle);
255  }
256  
~ConnectionReport()257  DynamicSensorManager::ConnectionReport::~ConnectionReport() {
258      ALOGV("Connection report dtor: name = %s, handle = %d", mSensor.name, mSensor.handle);
259  }
260  
261  const sensors_event_t& DynamicSensorManager::ConnectionReport::
generateConnectionEvent(int metaHandle)262          generateConnectionEvent(int metaHandle) {
263      if (!mGenerated) {
264          mEvent.sensor = metaHandle;
265          mEvent.type = SENSOR_TYPE_DYNAMIC_SENSOR_META;
266          mEvent.timestamp = elapsedRealtimeNano();
267          mEvent.dynamic_sensor_meta =
268                  (dynamic_sensor_meta_event_t) {true, mSensor.handle, &mSensor, {0}};
269          memcpy(&mEvent.dynamic_sensor_meta.uuid, &mUuid, sizeof(mEvent.dynamic_sensor_meta.uuid));
270          mGenerated = true;
271      }
272      return mEvent;
273  }
274  
275  void DynamicSensorManager::ConnectionReport::
fillDisconnectionEvent(sensors_event_t * event,int metaHandle,int handle)276          fillDisconnectionEvent(sensors_event_t* event, int metaHandle, int handle) {
277      memset(event, 0, sizeof(sensors_event_t));
278      event->version = sizeof(sensors_event_t);
279      event->sensor = metaHandle;
280      event->type = SENSOR_TYPE_DYNAMIC_SENSOR_META;
281      event->timestamp = elapsedRealtimeNano();
282      event->dynamic_sensor_meta.connected = false;
283      event->dynamic_sensor_meta.handle = handle;
284  }
285  
286  } // namespace SensorHalExt
287  } // namespace android
288