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