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 "SensorsHidlEnvironmentV1_0.h"
     18 
     19 #include <log/log.h>
     20 
     21 #include <vector>
     22 
     23 using ::android::hardware::hidl_vec;
     24 using ::android::hardware::sensors::V1_0::ISensors;
     25 using ::android::hardware::sensors::V1_0::Result;
     26 using ::android::hardware::sensors::V1_0::SensorInfo;
     27 
     28 bool SensorsHidlEnvironmentV1_0::resetHal() {
     29     // wait upto 100ms * 10 = 1s for hidl service.
     30     constexpr auto RETRY_DELAY = std::chrono::milliseconds(100);
     31 
     32     std::string step;
     33     bool succeed = false;
     34     for (size_t retry = 10; retry > 0; --retry) {
     35         // this do ... while is for easy error handling
     36         do {
     37             step = "getService()";
     38             sensors = ISensors::getService(
     39                 SensorsHidlEnvironmentV1_0::Instance()->getServiceName<ISensors>());
     40             if (sensors == nullptr) {
     41                 break;
     42             }
     43 
     44             step = "poll() check";
     45             // Poke ISensor service. If it has lingering connection from previous generation of
     46             // system server, it will kill itself. There is no intention to handle the poll result,
     47             // which will be done since the size is 0.
     48             if (!sensors->poll(0, [](auto, const auto&, const auto&) {}).isOk()) {
     49                 break;
     50             }
     51 
     52             step = "getSensorList";
     53             std::vector<SensorInfo> sensorList;
     54             if (!sensors
     55                      ->getSensorsList([&](const hidl_vec<SensorInfo>& list) {
     56                          sensorList.reserve(list.size());
     57                          for (size_t i = 0; i < list.size(); ++i) {
     58                              sensorList.push_back(list[i]);
     59                          }
     60                      })
     61                      .isOk()) {
     62                 break;
     63             }
     64 
     65             // stop each sensor individually
     66             step = "stop each sensor";
     67             bool ok = true;
     68             for (const auto& i : sensorList) {
     69                 if (!sensors->activate(i.sensorHandle, false).isOk()) {
     70                     ok = false;
     71                     break;
     72                 }
     73             }
     74             if (!ok) {
     75                 break;
     76             }
     77 
     78             // mark it done
     79             step = "done";
     80             succeed = true;
     81         } while (0);
     82 
     83         if (succeed) {
     84             return true;
     85         }
     86 
     87         // Delay 100ms before retry, hidl service is expected to come up in short time after crash.
     88         ALOGI("%s unsuccessful, try again soon (remaining retry %zu).", step.c_str(), retry - 1);
     89         std::this_thread::sleep_for(RETRY_DELAY);
     90     }
     91 
     92     sensors = nullptr;
     93     return false;
     94 }
     95 
     96 void SensorsHidlEnvironmentV1_0::startPollingThread() {
     97     mStopThread = false;
     98     mPollThread = std::thread(pollingThread, this, std::ref(mStopThread));
     99     mEvents.reserve(128);
    100 }
    101 
    102 void SensorsHidlEnvironmentV1_0::pollingThread(SensorsHidlEnvironmentV1_0* env,
    103                                                std::atomic_bool& stop) {
    104     ALOGD("polling thread start");
    105 
    106     while (!stop) {
    107         env->sensors->poll(
    108             64, [&](auto result, const auto& events, const auto& dynamicSensorsAdded) {
    109                 if (result != Result::OK ||
    110                     (events.size() == 0 && dynamicSensorsAdded.size() == 0) || stop) {
    111                     stop = true;
    112                     return;
    113                 }
    114 
    115                 for (const auto& e : events) {
    116                     env->addEvent(e);
    117                 }
    118             });
    119     }
    120     ALOGD("polling thread end");
    121 }