Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(489)

Unified Diff: extensions/browser/api/runtime/runtime_api.cc

Issue 1970613003: Add a new app API to enable watchdog behavior restarts in kiosk apps (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove unneeded include and forward declare Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: extensions/browser/api/runtime/runtime_api.cc
diff --git a/extensions/browser/api/runtime/runtime_api.cc b/extensions/browser/api/runtime/runtime_api.cc
index e62805e674289632f33a1786b7a89eac8b06d478..ef5202e1ad1c854cc7f8d8f03573d6af2fe0fd2f 100644
--- a/extensions/browser/api/runtime/runtime_api.cc
+++ b/extensions/browser/api/runtime/runtime_api.cc
@@ -10,6 +10,7 @@
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/metrics/histogram.h"
+#include "base/strings/string_number_conversions.h"
#include "base/values.h"
#include "base/version.h"
#include "content/public/browser/browser_context.h"
@@ -76,6 +77,12 @@ const char kPrefPreviousVersion[] = "previous_version";
// with the equivalent Pepper API.
const char kPackageDirectoryPath[] = "crxfs";
+// Preferece keys for storing the last successful restart on watchdog requests.
+const char kPrefRestartOnWatchdogTime[] = "restart_on_watchdog_time_prefs";
+const char kPrefLastRestartTime[] = "last_restart_on_watchdog_time";
+
+const int kMinDurationBetweenSuccessiveRestartsHours = 3;
+
void DispatchOnStartupEventImpl(BrowserContext* browser_context,
const std::string& extension_id,
bool first_call,
@@ -156,7 +163,9 @@ RuntimeAPI::RuntimeAPI(content::BrowserContext* context)
: browser_context_(context),
dispatch_chrome_updated_event_(false),
extension_registry_observer_(this),
- process_manager_observer_(this) {
+ process_manager_observer_(this),
+ minimum_duration_between_restarts_(base::TimeDelta::FromHours(
+ kMinDurationBetweenSuccessiveRestartsHours)) {
// RuntimeAPI is redirected in incognito, so |browser_context_| is never
// incognito.
DCHECK(!browser_context_->IsOffTheRecord());
@@ -321,10 +330,66 @@ bool RuntimeAPI::RestartDevice(std::string* error_message) {
return delegate_->RestartDevice(error_message);
}
+void RuntimeAPI::RestartDeviceOnWatchdogTimeout(
+ const Extension* extension,
+ int seconds,
+ const OnWatchdogTimeoutCallback& callback) {
+ if (seconds == -1) {
+ watchdog_timer_.Stop();
+ callback.Run(false, "Restart on watchdog was canceled.");
+ return;
+ }
+
+ watchdog_timer_.Stop();
xiyuan 2016/05/13 17:56:15 |watchdog_timer_| is a per-profile resource. We pr
afakhry 2016/05/14 01:27:35 Done.
+ watchdog_timer_.Start(
+ FROM_HERE, base::TimeDelta::FromSeconds(seconds),
+ base::Bind(&RuntimeAPI::OnRestartWatchdogTimeout, base::Unretained(this),
xiyuan 2016/05/13 17:56:15 nit: There is another Start on OneShotTimer interf
afakhry 2016/05/14 01:27:35 Yes, the problem with that interface is that I won
xiyuan 2016/05/16 18:25:17 Acknowledged.
+ extension, callback));
+}
+
bool RuntimeAPI::OpenOptionsPage(const Extension* extension) {
return delegate_->OpenOptionsPage(extension);
}
+void RuntimeAPI::OnRestartWatchdogTimeout(
+ const Extension* extension,
+ const OnWatchdogTimeoutCallback& callback) {
+ // Throttle restart requests that are received too soon successively.
+ base::TimeTicks now = base::TimeTicks::Now();
xiyuan 2016/05/13 17:56:15 Time is always a trick topic. base::TimeTicks is a
afakhry 2016/05/14 01:27:35 Thanks for providing the link. Changed it to base:
+ ExtensionPrefs* prefs = ExtensionPrefs::Get(browser_context_);
xiyuan 2016/05/13 17:56:15 Sorry for flipping on my suggestion. Let's store t
afakhry 2016/05/14 01:27:35 Done.
+ DCHECK(prefs);
+
+ const base::DictionaryValue* restart_on_watchdog_prefs = nullptr;
+ if (prefs->ReadPrefAsDictionary(extension->id(), kPrefRestartOnWatchdogTime,
+ &restart_on_watchdog_prefs)) {
+ double last_restart_ticks = 0.0;
+ if (restart_on_watchdog_prefs->GetDouble(kPrefLastRestartTime,
+ &last_restart_ticks)) {
+ base::TimeTicks last_time = base::TimeTicks::FromInternalValue(
+ static_cast<int64_t>(last_restart_ticks));
+ if ((now - last_time) < minimum_duration_between_restarts_) {
+ callback.Run(false, "Error: Called too soon since the last restart.");
+ // TODO(afakhry): Figure out what to do here. Do we restart later?
xiyuan 2016/05/13 17:56:15 We should still reboot but after the minimum reboo
afakhry 2016/05/14 01:27:35 Done. Rebooting after the minimum reboot time has
+ return;
+ }
+ }
+ }
+
+ std::string error_message;
+ const bool success = delegate_->RestartDevice(&error_message);
+
+ if (success) {
+ // Store |now| as the last successful restart request time.
+ base::DictionaryValue* prefs_to_update = new base::DictionaryValue();
+ prefs_to_update->SetDouble(kPrefLastRestartTime,
+ static_cast<double>(now.ToInternalValue()));
+ prefs->UpdateExtensionPref(extension->id(), kPrefRestartOnWatchdogTime,
+ prefs_to_update);
+ }
+
+ callback.Run(success, error_message);
+}
+
///////////////////////////////////////////////////////////////////////////////
// static
@@ -551,6 +616,37 @@ ExtensionFunction::ResponseAction RuntimeRestartFunction::Run() {
return RespondNow(NoArguments());
}
+ExtensionFunction::ResponseAction RuntimeRestartOnWatchdogFunction::Run() {
+ std::unique_ptr<api::runtime::RestartOnWatchdog::Params> params(
+ api::runtime::RestartOnWatchdog::Params::Create(*args_));
+ EXTENSION_FUNCTION_VALIDATE(params.get());
xiyuan 2016/05/13 17:56:15 Check ExtensionsBrowserClient::Get()->IsRunningInF
afakhry 2016/05/14 01:27:35 I added a TODO here instead, because I'll need mor
afakhry 2016/05/17 18:38:31 Now Done.
+ int seconds = params->seconds;
+
+ if (seconds < -1) {
+ return RespondNow(
+ Error("Invalid argument: *.", base::IntToString(seconds)));
+ }
+
+ RuntimeAPI::GetFactoryInstance()
+ ->Get(browser_context())
+ ->RestartDeviceOnWatchdogTimeout(
+ extension(), seconds,
+ base::Bind(&RuntimeRestartOnWatchdogFunction::OnWatchdogTimeout,
+ this));
+
+ return RespondLater();
+}
+
+void RuntimeRestartOnWatchdogFunction::OnWatchdogTimeout(
+ bool success,
+ const std::string& message) {
+ if (!success)
+ WriteToConsole(content::CONSOLE_MESSAGE_LEVEL_ERROR, message);
+
+ Respond(ArgumentList(
xiyuan 2016/05/13 17:56:15 I thought we would invoke the callback when the wa
afakhry 2016/05/14 01:27:35 Done. I made sure any previously scheduled callbac
+ api::runtime::RestartOnWatchdog::Results::Create(success, message)));
+}
+
ExtensionFunction::ResponseAction RuntimeGetPlatformInfoFunction::Run() {
runtime::PlatformInfo info;
if (!RuntimeAPI::GetFactoryInstance()

Powered by Google App Engine
This is Rietveld 408576698