You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
3.9 KiB
133 lines
3.9 KiB
/*
|
|
* Copyright (C) 2020 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 <signal.h>
|
|
#include <sys/time.h>
|
|
#include <unistd.h>
|
|
|
|
#include <algorithm>
|
|
#include <mutex>
|
|
#include <thread>
|
|
|
|
#include <android-base/logging.h>
|
|
#include <android-base/parsebool.h>
|
|
#include <android-base/parseint.h>
|
|
#include <android-base/properties.h>
|
|
#include <android-base/thread_annotations.h>
|
|
|
|
#include "property_monitor.h"
|
|
|
|
static constexpr char kAdbWatchdogProperty[] = "persist.adb.watchdog";
|
|
static constexpr char kTestHarnessProperty[] = "persist.sys.test_harness";
|
|
|
|
static constexpr unsigned int kDefaultAdbWatchdogTimeoutSeconds = 600;
|
|
static unsigned int g_watchdog_timeout_seconds;
|
|
|
|
static std::mutex g_watchdog_mutex [[clang::no_destroy]];
|
|
|
|
// The watchdog is "running" when it's enabled via property and there are no connected clients.
|
|
static bool g_watchdog_running GUARDED_BY(g_watchdog_mutex) = false;
|
|
|
|
static PropertyMonitor g_property_monitor [[clang::no_destroy]];
|
|
|
|
static void UpdateWatchdog() REQUIRES(g_watchdog_mutex) {
|
|
static std::once_flag once;
|
|
std::call_once(once, []() {
|
|
signal(SIGALRM, [](int) {
|
|
execl("/system/bin/reboot", "/system/bin/reboot", "bootloader", nullptr);
|
|
});
|
|
});
|
|
|
|
static bool alarm_set = false;
|
|
|
|
static auto Arm = []() {
|
|
LOG(INFO) << "adb watchdog armed, triggering in " << g_watchdog_timeout_seconds
|
|
<< " seconds";
|
|
alarm(g_watchdog_timeout_seconds);
|
|
alarm_set = true;
|
|
};
|
|
|
|
static auto Disarm = []() {
|
|
unsigned int previous = alarm(0);
|
|
if (previous != 0) {
|
|
LOG(INFO) << "adb watchdog disarmed with " << previous << " seconds left";
|
|
}
|
|
alarm_set = false;
|
|
};
|
|
|
|
bool watchdog_enabled = android::base::GetBoolProperty(
|
|
kAdbWatchdogProperty, android::base::GetBoolProperty(kTestHarnessProperty, false));
|
|
if (!watchdog_enabled) {
|
|
if (alarm_set) {
|
|
Disarm();
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (g_watchdog_running) {
|
|
if (!alarm_set) {
|
|
Arm();
|
|
}
|
|
} else {
|
|
Disarm();
|
|
}
|
|
}
|
|
|
|
namespace watchdog {
|
|
|
|
void Start() {
|
|
std::lock_guard<std::mutex> lock(g_watchdog_mutex);
|
|
g_watchdog_running = true;
|
|
UpdateWatchdog();
|
|
}
|
|
|
|
void Stop() {
|
|
std::lock_guard<std::mutex> lock(g_watchdog_mutex);
|
|
g_watchdog_running = false;
|
|
UpdateWatchdog();
|
|
}
|
|
|
|
void Initialize() {
|
|
for (auto& property : {kAdbWatchdogProperty, kTestHarnessProperty}) {
|
|
g_property_monitor.Add(property, [property](std::string value) {
|
|
LOG(INFO) << property << " set to '" << value << "'";
|
|
|
|
std::lock_guard<std::mutex> lock(g_watchdog_mutex);
|
|
UpdateWatchdog();
|
|
return true;
|
|
});
|
|
}
|
|
|
|
g_property_monitor.Add("persist.adb.watchdog.timeout_secs", [](std::string value) {
|
|
// This presumably isn't going to change while the watchdog is armed,
|
|
// so we don't need to recalculate a timer.
|
|
{
|
|
std::lock_guard<std::mutex> lock(g_watchdog_mutex);
|
|
if (!android::base::ParseUint(value, &g_watchdog_timeout_seconds)) {
|
|
g_watchdog_timeout_seconds = kDefaultAdbWatchdogTimeoutSeconds;
|
|
}
|
|
}
|
|
|
|
LOG(INFO) << "adb watchdog timeout set to " << g_watchdog_timeout_seconds << " seconds";
|
|
return true;
|
|
});
|
|
|
|
Start();
|
|
std::thread([]() { g_property_monitor.Run(); }).detach();
|
|
}
|
|
|
|
} // namespace watchdog
|