Home | History | Annotate | Download | only in default
      1 /*
      2  * Copyright (C) 2018 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 "Sensors.h"
     18 
     19 #include <android/hardware/sensors/2.0/types.h>
     20 #include <log/log.h>
     21 
     22 namespace android {
     23 namespace hardware {
     24 namespace sensors {
     25 namespace V2_0 {
     26 namespace implementation {
     27 
     28 using ::android::hardware::sensors::V1_0::Event;
     29 using ::android::hardware::sensors::V1_0::OperationMode;
     30 using ::android::hardware::sensors::V1_0::RateLevel;
     31 using ::android::hardware::sensors::V1_0::Result;
     32 using ::android::hardware::sensors::V1_0::SharedMemInfo;
     33 using ::android::hardware::sensors::V2_0::SensorTimeout;
     34 using ::android::hardware::sensors::V2_0::WakeLockQueueFlagBits;
     35 
     36 constexpr const char* kWakeLockName = "SensorsHAL_WAKEUP";
     37 
     38 Sensors::Sensors()
     39     : mEventQueueFlag(nullptr),
     40       mNextHandle(1),
     41       mOutstandingWakeUpEvents(0),
     42       mReadWakeLockQueueRun(false),
     43       mAutoReleaseWakeLockTime(0),
     44       mHasWakeLock(false) {
     45     AddSensor<AccelSensor>();
     46     AddSensor<GyroSensor>();
     47     AddSensor<AmbientTempSensor>();
     48     AddSensor<DeviceTempSensor>();
     49     AddSensor<PressureSensor>();
     50     AddSensor<MagnetometerSensor>();
     51     AddSensor<LightSensor>();
     52     AddSensor<ProximitySensor>();
     53     AddSensor<RelativeHumiditySensor>();
     54 }
     55 
     56 Sensors::~Sensors() {
     57     deleteEventFlag();
     58     mReadWakeLockQueueRun = false;
     59     mWakeLockThread.join();
     60 }
     61 
     62 // Methods from ::android::hardware::sensors::V2_0::ISensors follow.
     63 Return<void> Sensors::getSensorsList(getSensorsList_cb _hidl_cb) {
     64     std::vector<SensorInfo> sensors;
     65     for (const auto& sensor : mSensors) {
     66         sensors.push_back(sensor.second->getSensorInfo());
     67     }
     68 
     69     // Call the HIDL callback with the SensorInfo
     70     _hidl_cb(sensors);
     71 
     72     return Void();
     73 }
     74 
     75 Return<Result> Sensors::setOperationMode(OperationMode mode) {
     76     for (auto sensor : mSensors) {
     77         sensor.second->setOperationMode(mode);
     78     }
     79     return Result::OK;
     80 }
     81 
     82 Return<Result> Sensors::activate(int32_t sensorHandle, bool enabled) {
     83     auto sensor = mSensors.find(sensorHandle);
     84     if (sensor != mSensors.end()) {
     85         sensor->second->activate(enabled);
     86         return Result::OK;
     87     }
     88     return Result::BAD_VALUE;
     89 }
     90 
     91 Return<Result> Sensors::initialize(
     92     const ::android::hardware::MQDescriptorSync<Event>& eventQueueDescriptor,
     93     const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor,
     94     const sp<ISensorsCallback>& sensorsCallback) {
     95     Result result = Result::OK;
     96 
     97     // Ensure that all sensors are disabled
     98     for (auto sensor : mSensors) {
     99         sensor.second->activate(false /* enable */);
    100     }
    101 
    102     // Stop the Wake Lock thread if it is currently running
    103     if (mReadWakeLockQueueRun.load()) {
    104         mReadWakeLockQueueRun = false;
    105         mWakeLockThread.join();
    106     }
    107 
    108     // Save a reference to the callback
    109     mCallback = sensorsCallback;
    110 
    111     // Create the Event FMQ from the eventQueueDescriptor. Reset the read/write positions.
    112     mEventQueue =
    113         std::make_unique<EventMessageQueue>(eventQueueDescriptor, true /* resetPointers */);
    114 
    115     // Ensure that any existing EventFlag is properly deleted
    116     deleteEventFlag();
    117 
    118     // Create the EventFlag that is used to signal to the framework that sensor events have been
    119     // written to the Event FMQ
    120     if (EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag) != OK) {
    121         result = Result::BAD_VALUE;
    122     }
    123 
    124     // Create the Wake Lock FMQ that is used by the framework to communicate whenever WAKE_UP
    125     // events have been successfully read and handled by the framework.
    126     mWakeLockQueue =
    127         std::make_unique<WakeLockMessageQueue>(wakeLockDescriptor, true /* resetPointers */);
    128 
    129     if (!mCallback || !mEventQueue || !mWakeLockQueue || mEventQueueFlag == nullptr) {
    130         result = Result::BAD_VALUE;
    131     }
    132 
    133     // Start the thread to read events from the Wake Lock FMQ
    134     mReadWakeLockQueueRun = true;
    135     mWakeLockThread = std::thread(startReadWakeLockThread, this);
    136 
    137     return result;
    138 }
    139 
    140 Return<Result> Sensors::batch(int32_t sensorHandle, int64_t samplingPeriodNs,
    141                               int64_t /* maxReportLatencyNs */) {
    142     auto sensor = mSensors.find(sensorHandle);
    143     if (sensor != mSensors.end()) {
    144         sensor->second->batch(samplingPeriodNs);
    145         return Result::OK;
    146     }
    147     return Result::BAD_VALUE;
    148 }
    149 
    150 Return<Result> Sensors::flush(int32_t sensorHandle) {
    151     auto sensor = mSensors.find(sensorHandle);
    152     if (sensor != mSensors.end()) {
    153         return sensor->second->flush();
    154     }
    155     return Result::BAD_VALUE;
    156 }
    157 
    158 Return<Result> Sensors::injectSensorData(const Event& event) {
    159     auto sensor = mSensors.find(event.sensorHandle);
    160     if (sensor != mSensors.end()) {
    161         return sensor->second->injectEvent(event);
    162     }
    163 
    164     return Result::BAD_VALUE;
    165 }
    166 
    167 Return<void> Sensors::registerDirectChannel(const SharedMemInfo& /* mem */,
    168                                             registerDirectChannel_cb _hidl_cb) {
    169     _hidl_cb(Result::INVALID_OPERATION, -1 /* channelHandle */);
    170     return Return<void>();
    171 }
    172 
    173 Return<Result> Sensors::unregisterDirectChannel(int32_t /* channelHandle */) {
    174     return Result::INVALID_OPERATION;
    175 }
    176 
    177 Return<void> Sensors::configDirectReport(int32_t /* sensorHandle */, int32_t /* channelHandle */,
    178                                          RateLevel /* rate */, configDirectReport_cb _hidl_cb) {
    179     _hidl_cb(Result::INVALID_OPERATION, 0 /* reportToken */);
    180     return Return<void>();
    181 }
    182 
    183 void Sensors::postEvents(const std::vector<Event>& events, bool wakeup) {
    184     std::lock_guard<std::mutex> lock(mWriteLock);
    185     if (mEventQueue->write(events.data(), events.size())) {
    186         mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS));
    187 
    188         if (wakeup) {
    189             // Keep track of the number of outstanding WAKE_UP events in order to properly hold
    190             // a wake lock until the framework has secured a wake lock
    191             updateWakeLock(events.size(), 0 /* eventsHandled */);
    192         }
    193     }
    194 }
    195 
    196 void Sensors::updateWakeLock(int32_t eventsWritten, int32_t eventsHandled) {
    197     std::lock_guard<std::mutex> lock(mWakeLockLock);
    198     int32_t newVal = mOutstandingWakeUpEvents + eventsWritten - eventsHandled;
    199     if (newVal < 0) {
    200         mOutstandingWakeUpEvents = 0;
    201     } else {
    202         mOutstandingWakeUpEvents = newVal;
    203     }
    204 
    205     if (eventsWritten > 0) {
    206         // Update the time at which the last WAKE_UP event was sent
    207         mAutoReleaseWakeLockTime = ::android::uptimeMillis() +
    208                                    static_cast<uint32_t>(SensorTimeout::WAKE_LOCK_SECONDS) * 1000;
    209     }
    210 
    211     if (!mHasWakeLock && mOutstandingWakeUpEvents > 0 &&
    212         acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLockName) == 0) {
    213         mHasWakeLock = true;
    214     } else if (mHasWakeLock) {
    215         // Check if the wake lock should be released automatically if
    216         // SensorTimeout::WAKE_LOCK_SECONDS has elapsed since the last WAKE_UP event was written to
    217         // the Wake Lock FMQ.
    218         if (::android::uptimeMillis() > mAutoReleaseWakeLockTime) {
    219             ALOGD("No events read from wake lock FMQ for %d seconds, auto releasing wake lock",
    220                   SensorTimeout::WAKE_LOCK_SECONDS);
    221             mOutstandingWakeUpEvents = 0;
    222         }
    223 
    224         if (mOutstandingWakeUpEvents == 0 && release_wake_lock(kWakeLockName) == 0) {
    225             mHasWakeLock = false;
    226         }
    227     }
    228 }
    229 
    230 void Sensors::readWakeLockFMQ() {
    231     while (mReadWakeLockQueueRun.load()) {
    232         constexpr int64_t kReadTimeoutNs = 500 * 1000 * 1000;  // 500 ms
    233         uint32_t eventsHandled = 0;
    234 
    235         // Read events from the Wake Lock FMQ. Timeout after a reasonable amount of time to ensure
    236         // that any held wake lock is able to be released if it is held for too long.
    237         mWakeLockQueue->readBlocking(&eventsHandled, 1 /* count */, 0 /* readNotification */,
    238                                      static_cast<uint32_t>(WakeLockQueueFlagBits::DATA_WRITTEN),
    239                                      kReadTimeoutNs);
    240         updateWakeLock(0 /* eventsWritten */, eventsHandled);
    241     }
    242 }
    243 
    244 void Sensors::startReadWakeLockThread(Sensors* sensors) {
    245     sensors->readWakeLockFMQ();
    246 }
    247 
    248 void Sensors::deleteEventFlag() {
    249     status_t status = EventFlag::deleteEventFlag(&mEventQueueFlag);
    250     if (status != OK) {
    251         ALOGI("Failed to delete event flag: %d", status);
    252     }
    253 }
    254 
    255 }  // namespace implementation
    256 }  // namespace V2_0
    257 }  // namespace sensors
    258 }  // namespace hardware
    259 }  // namespace android
    260