Home | History | Annotate | Download | only in dynamic_sensor
      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 
     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 
     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 
     68 DynamicSensorManager::~DynamicSensorManager() {
     69     // free all daemons first
     70     mDaemonVector.clear();
     71 }
     72 
     73 bool DynamicSensorManager::owns(int handle) const {
     74     return handle >= mHandleRange.first && handle < mHandleRange.second;
     75 }
     76 
     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 
     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 
    106 int DynamicSensorManager::setDelay(int handle, nsecs_t sample_period) {
    107     return batch(handle, sample_period, 0);
    108 }
    109 
    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 
    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 
    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 
    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 
    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 
    227 int DynamicSensorManager::getNextAvailableHandle() {
    228     if (mNextHandle == mHandleRange.second) {
    229         return -1;
    230     }
    231     return mNextHandle++;
    232 }
    233 
    234 const sensor_t& DynamicSensorManager::getDynamicMetaSensor() const {
    235     return mMetaSensor;
    236 }
    237 
    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 
    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::
    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::
    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