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