Various upgrade_util improvements.
- upgrade_util.{cc,h} and friends are now only included in the build for
relevant platforms (desktop Chrome).
- upgrade_util::SetNewCommandLine now explicitly takes ownership of its
argument.
- A test seam has been added to RelaunchChromeBrowser. Tests may now
specify a callback to be run when relaunch takes place.
- Unexpected calls to RelaunchChromeBrowser in browser_tests and friends
now cause test failures (they previously attempted to launch Chrome).
- ScopedRelaunchChromeBrowserOverride is now available for tests of
scenarios that involved RelaunchChromeBrowser.
BUG=958893,989468
Change-Id: I8620e2bbe56e282934b94b3ea2ae52ef32f9d04a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1736707
Auto-Submit: Greg Thompson <[email protected]>
Reviewed-by: Gabriel Charette <[email protected]>
Reviewed-by: Marc Treib <[email protected]>
Commit-Queue: Greg Thompson <[email protected]>
Cr-Commit-Position: refs/heads/master@{#685466}
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index a75b4d38..06b0ffd 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -3023,11 +3023,6 @@
"first_run/first_run_internal_linux.cc",
"first_run/first_run_internal_mac.mm",
"first_run/first_run_internal_win.cc",
- "first_run/upgrade_util.h",
- "first_run/upgrade_util_mac.h",
- "first_run/upgrade_util_mac.mm",
- "first_run/upgrade_util_win.cc",
- "first_run/upgrade_util_win.h",
"font_family_cache.cc",
"font_family_cache.h",
"hid/chrome_hid_delegate.cc",
@@ -3701,7 +3696,6 @@
"browser_switcher/browser_switcher_service_win.h",
"downgrade/user_data_downgrade.cc",
"downgrade/user_data_downgrade.h",
- "first_run/upgrade_util.cc",
"notifications/win/notification_image_retainer.cc",
"notifications/win/notification_image_retainer.h",
"notifications/win/notification_template_builder.cc",
@@ -3867,7 +3861,6 @@
if (is_desktop_linux) {
# Desktop linux, doesn't count ChromeOS.
sources += [
- "first_run/upgrade_util.cc",
"first_run/upgrade_util_linux.cc",
"first_run/upgrade_util_linux.h",
"icon_loader_auralinux.cc",
@@ -3983,6 +3976,12 @@
if (!is_android && !is_chromeos) {
sources += [
+ "first_run/upgrade_util.cc",
+ "first_run/upgrade_util.h",
+ "first_run/upgrade_util_mac.h",
+ "first_run/upgrade_util_mac.mm",
+ "first_run/upgrade_util_win.cc",
+ "first_run/upgrade_util_win.h",
"lifetime/switch_utils.cc",
"lifetime/switch_utils.h",
"metrics/upgrade_metrics_provider.cc",
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index bb4b772..a68d42d 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -1458,7 +1458,7 @@
DLOG(WARNING) << "Shutting down current instance of the browser.";
chrome::AttemptExit();
- upgrade_util::SetNewCommandLine(new_cl.release());
+ upgrade_util::SetNewCommandLine(std::move(new_cl));
}
void BrowserProcessImpl::OnAutoupdateTimer() {
diff --git a/chrome/browser/first_run/scoped_relaunch_chrome_browser_override.cc b/chrome/browser/first_run/scoped_relaunch_chrome_browser_override.cc
new file mode 100644
index 0000000..fb46d8a
--- /dev/null
+++ b/chrome/browser/first_run/scoped_relaunch_chrome_browser_override.cc
@@ -0,0 +1,20 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/first_run/scoped_relaunch_chrome_browser_override.h"
+
+#include <utility>
+
+namespace upgrade_util {
+
+ScopedRelaunchChromeBrowserOverride::ScopedRelaunchChromeBrowserOverride(
+ RelaunchChromeBrowserCallback callback)
+ : previous_(
+ SetRelaunchChromeBrowserCallbackForTesting(std::move(callback))) {}
+
+ScopedRelaunchChromeBrowserOverride::~ScopedRelaunchChromeBrowserOverride() {
+ SetRelaunchChromeBrowserCallbackForTesting(std::move(previous_));
+}
+
+} // namespace upgrade_util
diff --git a/chrome/browser/first_run/scoped_relaunch_chrome_browser_override.h b/chrome/browser/first_run/scoped_relaunch_chrome_browser_override.h
new file mode 100644
index 0000000..e3cfda6
--- /dev/null
+++ b/chrome/browser/first_run/scoped_relaunch_chrome_browser_override.h
@@ -0,0 +1,31 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_FIRST_RUN_SCOPED_RELAUNCH_CHROME_BROWSER_OVERRIDE_H_
+#define CHROME_BROWSER_FIRST_RUN_SCOPED_RELAUNCH_CHROME_BROWSER_OVERRIDE_H_
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "chrome/browser/first_run/upgrade_util.h"
+
+namespace upgrade_util {
+
+// A test helper that overrides RelaunchChromeBrowser with a given callback for
+// the lifetime of an instance. The previous callback (or none) is restored
+// upon deletion.
+class ScopedRelaunchChromeBrowserOverride {
+ public:
+ explicit ScopedRelaunchChromeBrowserOverride(
+ RelaunchChromeBrowserCallback callback);
+ ~ScopedRelaunchChromeBrowserOverride();
+
+ private:
+ RelaunchChromeBrowserCallback previous_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedRelaunchChromeBrowserOverride);
+};
+
+} // namespace upgrade_util
+
+#endif // CHROME_BROWSER_FIRST_RUN_SCOPED_RELAUNCH_CHROME_BROWSER_OVERRIDE_H_
diff --git a/chrome/browser/first_run/upgrade_util.cc b/chrome/browser/first_run/upgrade_util.cc
index 7fe942a..68b4dfb 100644
--- a/chrome/browser/first_run/upgrade_util.cc
+++ b/chrome/browser/first_run/upgrade_util.cc
@@ -4,19 +4,44 @@
#include "chrome/browser/first_run/upgrade_util.h"
+#include <utility>
+
+#include "base/callback.h"
#include "base/command_line.h"
#include "base/logging.h"
+#include "build/build_config.h"
+#include "content/public/browser/browser_thread.h"
namespace {
-base::CommandLine* command_line;
+#if !defined(OS_MACOSX)
+base::CommandLine* command_line = nullptr;
+#endif
+
+// A test seam for whole-browser tests to override browser relaunch.
+upgrade_util::RelaunchChromeBrowserCallback*
+ relaunch_chrome_browser_callback_for_testing = nullptr;
} // namespace
namespace upgrade_util {
-void SetNewCommandLine(base::CommandLine* new_command_line) {
- command_line = new_command_line;
+// Forward-declaration of the platform-specific implementation.
+bool RelaunchChromeBrowserImpl(const base::CommandLine& command_line);
+
+bool RelaunchChromeBrowser(const base::CommandLine& command_line) {
+ if (relaunch_chrome_browser_callback_for_testing)
+ return relaunch_chrome_browser_callback_for_testing->Run(command_line);
+
+ return RelaunchChromeBrowserImpl(command_line);
+}
+
+#if !defined(OS_MACOSX)
+
+void SetNewCommandLine(std::unique_ptr<base::CommandLine> new_command_line) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ delete command_line;
+ command_line = new_command_line.release();
}
void RelaunchChromeBrowserWithNewCommandLineIfNeeded() {
@@ -27,8 +52,33 @@
DLOG(WARNING) << "Launched a new instance of the browser.";
}
delete command_line;
- command_line = NULL;
+ command_line = nullptr;
}
}
+#endif // !defined(OS_MACOSX)
+
+RelaunchChromeBrowserCallback SetRelaunchChromeBrowserCallbackForTesting(
+ RelaunchChromeBrowserCallback callback) {
+ // Take ownership of the current test callback so it can be returned.
+ RelaunchChromeBrowserCallback previous =
+ relaunch_chrome_browser_callback_for_testing
+ ? std::move(*relaunch_chrome_browser_callback_for_testing)
+ : RelaunchChromeBrowserCallback();
+
+ // Move the caller's callback into the global, alloc'ing or freeing as needed.
+ auto memory = base::WrapUnique(relaunch_chrome_browser_callback_for_testing);
+ if (callback) {
+ if (!memory)
+ memory = std::make_unique<RelaunchChromeBrowserCallback>();
+ *memory = std::move(callback);
+ } else if (memory) {
+ memory.reset();
+ }
+ relaunch_chrome_browser_callback_for_testing = memory.release();
+
+ // Return the previous callback.
+ return previous;
+}
+
} // namespace upgrade_util
diff --git a/chrome/browser/first_run/upgrade_util.h b/chrome/browser/first_run/upgrade_util.h
index 93e1c6d..859b9a09 100644
--- a/chrome/browser/first_run/upgrade_util.h
+++ b/chrome/browser/first_run/upgrade_util.h
@@ -5,16 +5,15 @@
#ifndef CHROME_BROWSER_FIRST_RUN_UPGRADE_UTIL_H_
#define CHROME_BROWSER_FIRST_RUN_UPGRADE_UTIL_H_
+#include <memory>
+
+#include "base/callback_forward.h"
#include "build/build_config.h"
#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
#error Not used on Android or ChromeOS
#endif
-#if defined(OS_WIN)
-#include <string>
-#endif
-
namespace base {
class CommandLine;
}
@@ -27,10 +26,12 @@
#if !defined(OS_MACOSX)
-void SetNewCommandLine(base::CommandLine* new_command_line);
+// Sets a command line to be used to relaunch the browser upon exit.
+void SetNewCommandLine(std::unique_ptr<base::CommandLine> new_command_line);
-// Launches a new instance of the browser if the current instance in persistent
-// mode an upgrade is detected.
+// Launches a new instance of the browser using a command line previously
+// provided to SetNewCommandLine. This is typically used to finalize an in-use
+// update that was detected while the browser was in persistent mode.
void RelaunchChromeBrowserWithNewCommandLineIfNeeded();
// Windows:
@@ -42,6 +43,15 @@
#endif // !defined(OS_MACOSX)
+using RelaunchChromeBrowserCallback =
+ base::RepeatingCallback<bool(const base::CommandLine&)>;
+
+// Sets |callback| to be run to process a RelaunchChromeBrowser request. This
+// is a test seam for whole-browser tests. See
+// ScopedRelaunchChromeBrowserOverride for convenience.
+RelaunchChromeBrowserCallback SetRelaunchChromeBrowserCallbackForTesting(
+ RelaunchChromeBrowserCallback callback);
+
} // namespace upgrade_util
#endif // CHROME_BROWSER_FIRST_RUN_UPGRADE_UTIL_H_
diff --git a/chrome/browser/first_run/upgrade_util_linux.cc b/chrome/browser/first_run/upgrade_util_linux.cc
index 7396dc6..eef5298 100644
--- a/chrome/browser/first_run/upgrade_util_linux.cc
+++ b/chrome/browser/first_run/upgrade_util_linux.cc
@@ -21,7 +21,7 @@
namespace upgrade_util {
-bool RelaunchChromeBrowser(const base::CommandLine& command_line) {
+bool RelaunchChromeBrowserImpl(const base::CommandLine& command_line) {
base::LaunchOptions options;
// Don't set NO_NEW_PRIVS on the relaunched browser process.
options.allow_new_privs = true;
diff --git a/chrome/browser/first_run/upgrade_util_mac.mm b/chrome/browser/first_run/upgrade_util_mac.mm
index f24c53e..d08b7f5 100644
--- a/chrome/browser/first_run/upgrade_util_mac.mm
+++ b/chrome/browser/first_run/upgrade_util_mac.mm
@@ -286,7 +286,7 @@
return !other_instances_exist;
}
-bool RelaunchChromeBrowser(const base::CommandLine& command_line) {
+bool RelaunchChromeBrowserImpl(const base::CommandLine& command_line) {
upgrade_util::ThisAndOtherUserCounts counts =
upgrade_util::GetCountOfOtherInstancesOfThisBinary();
const int other_instances = counts.this_user_count + counts.other_user_count;
diff --git a/chrome/browser/first_run/upgrade_util_win.cc b/chrome/browser/first_run/upgrade_util_win.cc
index 8d77b39..f8fab15 100644
--- a/chrome/browser/first_run/upgrade_util_win.cc
+++ b/chrome/browser/first_run/upgrade_util_win.cc
@@ -95,7 +95,7 @@
namespace upgrade_util {
-bool RelaunchChromeBrowser(const base::CommandLine& command_line) {
+bool RelaunchChromeBrowserImpl(const base::CommandLine& command_line) {
base::FilePath chrome_exe;
if (!base::PathService::Get(base::FILE_EXE, &chrome_exe)) {
NOTREACHED();