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 }