/* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "SensorsHidlEnvironmentV1_0.h" #include #include using ::android::hardware::hidl_vec; using ::android::hardware::sensors::V1_0::ISensors; using ::android::hardware::sensors::V1_0::Result; using ::android::hardware::sensors::V1_0::SensorInfo; void SensorsHidlEnvironmentV1_0::HidlTearDown() { mStopThread = true; if (mPollThread.joinable()) { mPollThread.detach(); } } bool SensorsHidlEnvironmentV1_0::resetHal() { // wait upto 100ms * 10 = 1s for hidl service. constexpr auto RETRY_DELAY = std::chrono::milliseconds(100); std::string step; bool succeed = false; for (size_t retry = 10; retry > 0; --retry) { // this do ... while is for easy error handling do { step = "getService()"; sensors = ISensors::getService(mServiceName); if (sensors == nullptr) { break; } step = "poll() check"; // Poke ISensor service. If it has lingering connection from previous generation of // system server, it will kill itself. There is no intention to handle the poll result, // which will be done since the size is 0. if (!sensors->poll(0, [](auto, const auto&, const auto&) {}).isOk()) { break; } step = "getSensorList"; std::vector sensorList; if (!sensors ->getSensorsList([&](const hidl_vec& list) { sensorList.reserve(list.size()); for (size_t i = 0; i < list.size(); ++i) { sensorList.push_back(list[i]); } }) .isOk()) { break; } // stop each sensor individually step = "stop each sensor"; bool ok = true; for (const auto& i : sensorList) { if (!sensors->activate(i.sensorHandle, false).isOk()) { ok = false; break; } } if (!ok) { break; } // mark it done step = "done"; succeed = true; } while (0); if (succeed) { return true; } // Delay 100ms before retry, hidl service is expected to come up in short time after crash. ALOGI("%s unsuccessful, try again soon (remaining retry %zu).", step.c_str(), retry - 1); std::this_thread::sleep_for(RETRY_DELAY); } sensors = nullptr; return false; } void SensorsHidlEnvironmentV1_0::startPollingThread() { mStopThread = false; mPollThread = std::thread(pollingThread, this, std::ref(mStopThread)); mEvents.reserve(128); } void SensorsHidlEnvironmentV1_0::pollingThread(SensorsHidlEnvironmentV1_0* env, std::atomic_bool& stop) { ALOGD("polling thread start"); while (!stop) { if (!env->sensors ->poll(64, [&](auto result, const auto& events, const auto& dynamicSensorsAdded) { if (result != Result::OK || (events.size() == 0 && dynamicSensorsAdded.size() == 0) || stop) { stop = true; return; } for (const auto& e : events) { env->addEvent(e); } }) .isOk()) { break; } } ALOGD("polling thread end"); }