Home | History | Annotate | Download | only in functional
      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 "SensorsHidlEnvironmentV2_0.h"
     18 
     19 #include <android/hardware/sensors/2.0/types.h>
     20 #include <log/log.h>
     21 
     22 #include <algorithm>
     23 #include <vector>
     24 
     25 using ::android::hardware::EventFlag;
     26 using ::android::hardware::hidl_vec;
     27 using ::android::hardware::Return;
     28 using ::android::hardware::sensors::V1_0::Result;
     29 using ::android::hardware::sensors::V1_0::SensorInfo;
     30 using ::android::hardware::sensors::V2_0::EventQueueFlagBits;
     31 using ::android::hardware::sensors::V2_0::ISensors;
     32 using ::android::hardware::sensors::V2_0::ISensorsCallback;
     33 
     34 template <typename EnumType>
     35 constexpr typename std::underlying_type<EnumType>::type asBaseType(EnumType value) {
     36     return static_cast<typename std::underlying_type<EnumType>::type>(value);
     37 }
     38 
     39 constexpr size_t SensorsHidlEnvironmentV2_0::MAX_RECEIVE_BUFFER_EVENT_COUNT;
     40 
     41 struct SensorsCallback : ISensorsCallback {
     42     Return<void> onDynamicSensorsConnected(const hidl_vec<SensorInfo>& /* sensorInfos */) {
     43         return Return<void>();
     44     }
     45 
     46     Return<void> onDynamicSensorsDisconnected(const hidl_vec<int32_t>& /* sensorHandles */) {
     47         return Return<void>();
     48     }
     49 };
     50 
     51 bool SensorsHidlEnvironmentV2_0::resetHal() {
     52     bool succeed = false;
     53     do {
     54         mSensors = ISensors::getService(
     55             SensorsHidlEnvironmentV2_0::Instance()->getServiceName<ISensors>());
     56         if (mSensors == nullptr) {
     57             break;
     58         }
     59 
     60         // Initialize FMQs
     61         mEventQueue = std::make_unique<EventMessageQueue>(MAX_RECEIVE_BUFFER_EVENT_COUNT,
     62                                                           true /* configureEventFlagWord */);
     63 
     64         mWakeLockQueue = std::make_unique<WakeLockQueue>(MAX_RECEIVE_BUFFER_EVENT_COUNT,
     65                                                          true /* configureEventFlagWord */);
     66 
     67         if (mEventQueue == nullptr || mWakeLockQueue == nullptr) {
     68             break;
     69         }
     70 
     71         EventFlag::deleteEventFlag(&mEventQueueFlag);
     72         EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag);
     73         if (mEventQueueFlag == nullptr) {
     74             break;
     75         }
     76 
     77         mSensors->initialize(*mEventQueue->getDesc(), *mWakeLockQueue->getDesc(),
     78                              new SensorsCallback());
     79 
     80         std::vector<SensorInfo> sensorList;
     81         if (!mSensors->getSensorsList([&](const hidl_vec<SensorInfo>& list) { sensorList = list; })
     82                  .isOk()) {
     83             break;
     84         }
     85 
     86         // stop each sensor individually
     87         bool ok = true;
     88         for (const auto& i : sensorList) {
     89             if (!mSensors->activate(i.sensorHandle, false).isOk()) {
     90                 ok = false;
     91                 break;
     92             }
     93         }
     94         if (!ok) {
     95             break;
     96         }
     97 
     98         // mark it done
     99         succeed = true;
    100     } while (0);
    101 
    102     if (!succeed) {
    103         mSensors = nullptr;
    104     }
    105 
    106     return succeed;
    107 }
    108 
    109 void SensorsHidlEnvironmentV2_0::HidlTearDown() {
    110     mStopThread = true;
    111 
    112     if (mEventQueueFlag != nullptr) {
    113         // Wake up the event queue so the poll thread can exit
    114         mEventQueueFlag->wake(asBaseType(EventQueueFlagBits::READ_AND_PROCESS));
    115         if (mPollThread.joinable()) {
    116             mPollThread.join();
    117         }
    118 
    119         EventFlag::deleteEventFlag(&mEventQueueFlag);
    120     }
    121 }
    122 
    123 void SensorsHidlEnvironmentV2_0::startPollingThread() {
    124     mStopThread = false;
    125     mPollThread = std::thread(pollingThread, this);
    126     mEvents.reserve(MAX_RECEIVE_BUFFER_EVENT_COUNT);
    127 }
    128 
    129 void SensorsHidlEnvironmentV2_0::readEvents() {
    130     size_t availableEvents = mEventQueue->availableToRead();
    131 
    132     if (availableEvents == 0) {
    133         uint32_t eventFlagState = 0;
    134 
    135         mEventQueueFlag->wait(asBaseType(EventQueueFlagBits::READ_AND_PROCESS), &eventFlagState);
    136         availableEvents = mEventQueue->availableToRead();
    137     }
    138 
    139     size_t eventsToRead = std::min(availableEvents, mEventBuffer.size());
    140     if (eventsToRead > 0) {
    141         if (mEventQueue->read(mEventBuffer.data(), eventsToRead)) {
    142             mEventQueueFlag->wake(asBaseType(EventQueueFlagBits::EVENTS_READ));
    143             for (size_t i = 0; i < eventsToRead; i++) {
    144                 addEvent(mEventBuffer[i]);
    145             }
    146         }
    147     }
    148 }
    149 
    150 void SensorsHidlEnvironmentV2_0::pollingThread(SensorsHidlEnvironmentV2_0* env) {
    151     ALOGD("polling thread start");
    152 
    153     while (!env->mStopThread.load()) {
    154         env->readEvents();
    155     }
    156 
    157     ALOGD("polling thread end");
    158 }
    159