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