• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
resetHal()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 
startPollingThread()96 void SensorsHidlEnvironmentV1_0::startPollingThread() {
97     mStopThread = false;
98     mPollThread = std::thread(pollingThread, this, std::ref(mStopThread));
99     mEvents.reserve(128);
100 }
101 
pollingThread(SensorsHidlEnvironmentV1_0 * env,std::atomic_bool & stop)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 }