Commit b5173c95 authored by Sorin Jianu's avatar Sorin Jianu Committed by Commit Bot

Split AppInstall and AppInstallController.

This is an iteration to make the implementation of --install
cross-platform.

SplashScreen and AppInstallController are injected by MakeAppInstall
implementation using two closures. The Windows code has working
objects for the two, while the other platforms use do-nothing stubs.

There is a small change in the integration test to invoke Wake for
the Windows execution path. The tests pass without the change and
removing this platform difference in the test execution seems useful.

Change-Id: Ie3c75d52742aafc7f2f96e16cc64583f501018f7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2385896
Commit-Queue: Sorin Jianu <sorin@chromium.org>
Reviewed-by: default avatarJoshua Pawlicki <waffles@chromium.org>
Cr-Commit-Position: refs/heads/master@{#804958}
parent 349a4d65
...@@ -55,6 +55,7 @@ if (is_win || is_mac) { ...@@ -55,6 +55,7 @@ if (is_win || is_mac) {
"registration_data.cc", "registration_data.cc",
"registration_data.h", "registration_data.h",
"service_scope.h", "service_scope.h",
"splash_screen.h",
"unzipper.cc", "unzipper.cc",
"unzipper.h", "unzipper.h",
"update_service.cc", "update_service.cc",
...@@ -83,6 +84,8 @@ if (is_win || is_mac) { ...@@ -83,6 +84,8 @@ if (is_win || is_mac) {
sources = [ sources = [
"app/app.cc", "app/app.cc",
"app/app.h", "app/app.h",
"app/app_install.cc",
"app/app_install.h",
"app/app_register.cc", "app/app_register.cc",
"app/app_register.h", "app/app_register.h",
"app/app_server.cc", "app/app_server.cc",
...@@ -164,6 +167,7 @@ if (is_win || is_mac) { ...@@ -164,6 +167,7 @@ if (is_win || is_mac) {
":base", ":base",
":version_header", ":version_header",
"//base", "//base",
"//base:i18n",
"//chrome/updater/device_management", "//chrome/updater/device_management",
"//components/crash/core/common:crash_key", "//components/crash/core/common:crash_key",
"//components/crx_file:crx_file", "//components/crx_file:crx_file",
...@@ -227,46 +231,6 @@ if (is_win || is_mac) { ...@@ -227,46 +231,6 @@ if (is_win || is_mac) {
output = "$target_gen_dir/updater_version.h" output = "$target_gen_dir/updater_version.h"
} }
# This build target is defined to minimize the impact of -Wno-missing-braces
# compiler switch. In the future it might be possible to isolate the
# dependency of ATL in the UI so ATL headers are not visible in the
# compilation units outside the UI itself.
# TODO(sorin): https://crbug.com/1014311
source_set("app_install") {
sources = [ "app/app_install.h" ]
if (is_win) {
sources += [ "win/app_install.cc" ]
}
deps = [
":lib",
"//base",
"//chrome/updater:base",
"//chrome/updater:version_header",
]
if (is_mac) {
deps += [ "//chrome/updater/mac:updater_setup_sources" ]
}
if (is_win) {
deps += [
"//base:i18n",
"//chrome/updater/win:install_progress_observer",
"//chrome/updater/win:lib",
"//chrome/updater/win/ui",
"//components/prefs",
"//components/update_client",
]
}
allow_circular_includes_from = [ ":lib" ]
if (is_win) {
cflags_cc = [ "-Wno-missing-braces" ]
}
}
source_set("updater_tests_support") { source_set("updater_tests_support") {
testonly = true testonly = true
......
// Copyright 2020 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/updater/app/app_install.h"
#include <utility>
#include "base/bind.h"
#include "base/callback.h"
#include "base/check.h"
#include "base/command_line.h"
#include "base/i18n/icu_util.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/version.h"
#include "build/build_config.h"
#include "chrome/updater/constants.h"
#include "chrome/updater/control_service.h"
#include "chrome/updater/persisted_data.h"
#include "chrome/updater/prefs.h"
#include "chrome/updater/setup.h"
#include "chrome/updater/updater_version.h"
#include "components/prefs/pref_service.h"
namespace updater {
#if !defined(OS_WIN)
namespace {
class SplashScreenImpl : public SplashScreen {
public:
// Overrides for SplashScreen.
void Show() override {}
void Dismiss(base::OnceClosure callback) override {
base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE,
std::move(callback));
}
};
class AppInstallControllerImpl : public AppInstallController {
public:
// Override for AppInstallController.
void InstallApp(const std::string& app_id,
base::OnceCallback<void(int)> callback) override {
base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), 0));
}
protected:
~AppInstallControllerImpl() override = default;
};
} // namespace
scoped_refptr<App> MakeAppInstall() {
return base::MakeRefCounted<AppInstall>(
base::BindRepeating([]() -> std::unique_ptr<SplashScreen> {
return std::make_unique<SplashScreenImpl>();
}),
base::BindRepeating([]() -> scoped_refptr<AppInstallController> {
return base::MakeRefCounted<AppInstallControllerImpl>();
}));
}
#endif // !defined(OS_WIN)
AppInstall::AppInstall(SplashScreen::Maker splash_screen_maker,
AppInstallController::Maker app_install_controller_maker)
: splash_screen_maker_(std::move(splash_screen_maker)),
app_install_controller_maker_(app_install_controller_maker) {
DCHECK(splash_screen_maker_);
DCHECK(app_install_controller_maker_);
}
AppInstall::~AppInstall() = default;
void AppInstall::Initialize() {
base::i18n::InitializeICU();
// Creating |global_prefs_| requires acquiring a global lock, and this lock is
// typically owned by the RPC server. That means that if the server is
// running, the following code will block, and the install will not proceed
// until the server releases the lock.
global_prefs_ = CreateGlobalPrefs();
local_prefs_ = CreateLocalPrefs();
}
void AppInstall::FirstTaskRun() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(base::ThreadTaskRunnerHandle::IsSet());
splash_screen_ = splash_screen_maker_.Run();
splash_screen_->Show();
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE,
{base::MayBlock(), base::TaskPriority::USER_BLOCKING,
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
base::BindOnce([]() { return InstallCandidate(false); }),
base::BindOnce(
[](SplashScreen* splash_screen, base::OnceCallback<void(int)> done,
int result) {
splash_screen->Dismiss(base::BindOnce(std::move(done), result));
},
splash_screen_.get(),
base::BindOnce(&AppInstall::InstallCandidateDone, this)));
}
// Updates the prefs if installing the updater is successful, then continue
// installing the application if --app-id is specified on the command line.
void AppInstall::InstallCandidateDone(int result) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (result != 0) {
Shutdown(result);
return;
}
// Invoke |HandleAppId| to continue the execution flow.
MakeActive(base::BindOnce(&AppInstall::HandleAppId, this));
}
void AppInstall::HandleAppId() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// This releases the prefs lock, and the RPC server can be started.
global_prefs_ = nullptr;
local_prefs_ = nullptr;
// If no app id is provided, then invoke ControlService::Run to wake
// this version of the updater, do an update check, and possibly promote
// this version as a result.
const std::string app_id =
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(kAppIdSwitch);
if (app_id.empty()) {
// The instance of |CreateControlService| has sequence affinity. Bind it
// in the closure to ensure it is released in this sequence.
scoped_refptr<ControlService> control_service = CreateControlService();
control_service->Run(base::BindOnce(
[](scoped_refptr<ControlService> /*control_service*/,
scoped_refptr<AppInstall> app_install) { app_install->Shutdown(0); },
control_service, base::WrapRefCounted(this)));
return;
}
app_install_controller_ = app_install_controller_maker_.Run();
app_install_controller_->InstallApp(
app_id, base::BindOnce(&AppInstall::Shutdown, this));
}
// TODO(crbug.com/1109231) - this is a temporary workaround.
void AppInstall::MakeActive(base::OnceClosure done) {
local_prefs_->SetQualified(true);
local_prefs_->GetPrefService()->CommitPendingWrite(base::BindOnce(
[](base::OnceClosure done, PrefService* pref_service) {
DCHECK(pref_service);
auto persisted_data = base::MakeRefCounted<PersistedData>(pref_service);
persisted_data->SetProductVersion(
kUpdaterAppId, base::Version(UPDATER_VERSION_STRING));
pref_service->CommitPendingWrite(std::move(done));
},
std::move(done), global_prefs_->GetPrefService()));
}
} // namespace updater
...@@ -5,11 +5,91 @@ ...@@ -5,11 +5,91 @@
#ifndef CHROME_UPDATER_APP_APP_INSTALL_H_ #ifndef CHROME_UPDATER_APP_APP_INSTALL_H_
#define CHROME_UPDATER_APP_APP_INSTALL_H_ #define CHROME_UPDATER_APP_APP_INSTALL_H_
#include "base/memory/scoped_refptr.h" #include <memory>
#include <string>
#include "base/callback_forward.h"
#include "base/memory/ref_counted.h"
#include "base/sequence_checker.h"
#include "chrome/updater/app/app.h"
#include "chrome/updater/splash_screen.h"
namespace base {
class TaskRunner;
}
namespace updater { namespace updater {
class App; class LocalPrefs;
class GlobalPrefs;
// This class defines an interface for installing an application. The interface
// is intended to be implemented for scenerios where UI and RPC calls to
// |UpdateService| are involved, hence the word `controller` in the name of
// the ]interface.
class AppInstallController
: public base::RefCountedThreadSafe<AppInstallController> {
public:
using Maker = base::RepeatingCallback<scoped_refptr<AppInstallController>()>;
virtual void InstallApp(const std::string& app_id,
base::OnceCallback<void(int)> callback) = 0;
protected:
virtual ~AppInstallController() = default;
private:
friend class base::RefCountedThreadSafe<AppInstallController>;
};
// Sets the updater up, shows up a splash screen, then installs an application
// while displaying the UI progress window.
class AppInstall : public App {
public:
AppInstall(SplashScreen::Maker splash_screen_maker,
AppInstallController::Maker app_install_controller_maker);
private:
~AppInstall() override;
// Overrides for App.
void Initialize() override;
void FirstTaskRun() override;
void InstallCandidateDone(int result);
// Handles the --app-id command line argument, and triggers installing of the
// corresponding app-id if the argument is present.
void HandleAppId();
// Makes this version of the updater active, self-registers for updates, then
// runs the |done| closure.
void MakeActive(base::OnceClosure done);
// Bound to the main sequence.
SEQUENCE_CHECKER(sequence_checker_);
// Creates instances of |SplashScreen|.
SplashScreen::Maker splash_screen_maker_;
// Creates instances of |AppInstallController|.
AppInstallController::Maker app_install_controller_maker_;
// The splash screen has a fading effect. That means that the splash screen
// needs to be alive for a while, until the fading effect is over.
std::unique_ptr<SplashScreen> splash_screen_;
scoped_refptr<AppInstallController> app_install_controller_;
// These prefs objects are used to make the updater active and register this
// version of the updater for self-updates.
//
// TODO(crbug.com/1109231) - this is a temporary workaround until a better
// fix is found.
std::unique_ptr<LocalPrefs> local_prefs_;
std::unique_ptr<GlobalPrefs> global_prefs_;
scoped_refptr<base::TaskRunner> make_active_task_runner_;
};
scoped_refptr<App> MakeAppInstall(); scoped_refptr<App> MakeAppInstall();
......
...@@ -12,7 +12,6 @@ group("mac") { ...@@ -12,7 +12,6 @@ group("mac") {
":browser_install_script", ":browser_install_script",
":updater_bundle", ":updater_bundle",
":updater_install_script", ":updater_install_script",
"//chrome/updater:app_install",
"//chrome/updater/mac/signing", "//chrome/updater/mac/signing",
] ]
} }
...@@ -61,7 +60,6 @@ mac_app_bundle("updater_bundle") { ...@@ -61,7 +60,6 @@ mac_app_bundle("updater_bundle") {
deps = [ deps = [
":network_fetcher_sources", ":network_fetcher_sources",
":updater_setup_sources", ":updater_setup_sources",
"//chrome/updater:app_install",
"//chrome/updater:lib", "//chrome/updater:lib",
] ]
} }
...@@ -169,7 +167,6 @@ source_set("updater_setup_tests") { ...@@ -169,7 +167,6 @@ source_set("updater_setup_tests") {
"//base", "//base",
"//base/test:test_support", "//base/test:test_support",
"//chrome/common:constants", "//chrome/common:constants",
"//chrome/updater:app_install",
"//testing/gtest", "//testing/gtest",
] ]
} }
......
// Copyright 2020 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_UPDATER_SPLASH_SCREEN_H_
#define CHROME_UPDATER_SPLASH_SCREEN_H_
#include <memory>
#include "base/callback_forward.h"
namespace updater {
// Displays a splash screen during install.
class SplashScreen {
public:
using Maker = base::RepeatingCallback<std::unique_ptr<SplashScreen>()>;
virtual ~SplashScreen() = default;
virtual void Show() = 0;
virtual void Dismiss(base::OnceClosure callback) = 0;
};
} // namespace updater
#endif // CHROME_UPDATER_SPLASH_SCREEN_H_
...@@ -69,8 +69,8 @@ TEST_F(IntegrationTest, InstallAndPromote) { ...@@ -69,8 +69,8 @@ TEST_F(IntegrationTest, InstallAndPromote) {
ExpectActiveVersion(UPDATER_VERSION_STRING); ExpectActiveVersion(UPDATER_VERSION_STRING);
#else #else
ExpectActiveVersion("0"); ExpectActiveVersion("0");
RunWake(0); // Candidate qualifies and promotes to active.
#endif #endif
RunWake(0); // Candidate qualifies and promotes to active.
ExpectActiveVersion(UPDATER_VERSION_STRING); ExpectActiveVersion(UPDATER_VERSION_STRING);
ExpectActive(); ExpectActive();
Uninstall(); Uninstall();
......
...@@ -36,8 +36,8 @@ ...@@ -36,8 +36,8 @@
// Instructions For Windows. // Instructions For Windows.
// - To install only the updater, run "updatersetup.exe" from the build out dir. // - To install only the updater, run "updatersetup.exe" from the build out dir.
// - To install Chrome and the updater, do the same but use the --appid: // - To install Chrome and the updater, do the same but use the --app-id:
// updatersetup.exe --appid={8A69D345-D564-463c-AFF1-A69D9E530F96} // updatersetup.exe --app-id={8A69D345-D564-463c-AFF1-A69D9E530F96}
// - To uninstall, run "updater.exe --uninstall" from its install directory, // - To uninstall, run "updater.exe --uninstall" from its install directory,
// which is under %LOCALAPPDATA%\Google\GoogleUpdater, or from the |out| // which is under %LOCALAPPDATA%\Google\GoogleUpdater, or from the |out|
// directory of the build. // directory of the build.
......
...@@ -25,10 +25,10 @@ executable("updater") { ...@@ -25,10 +25,10 @@ executable("updater") {
configs += [ "//build/config/win:windowed" ] configs += [ "//build/config/win:windowed" ]
deps = [ deps = [
":app_install_controller",
":lib", ":lib",
":version_resources", ":version_resources",
"//build/win:default_exe_manifest", "//build/win:default_exe_manifest",
"//chrome/updater:app_install",
"//chrome/updater:lib", "//chrome/updater:lib",
"//chrome/updater/win/ui:ui_resources", "//chrome/updater/win/ui:ui_resources",
] ]
...@@ -136,6 +136,33 @@ source_set("install_progress_observer") { ...@@ -136,6 +136,33 @@ source_set("install_progress_observer") {
deps = [ "//base" ] deps = [ "//base" ]
} }
# This build target is defined to minimize the impact of -Wno-missing-braces
# compiler switch. In the future it might be possible to isolate the
# dependency of ATL in the UI so ATL headers are not visible in the
# compilation units outside the UI itself.
# TODO(sorin): https://crbug.com/1014311
source_set("app_install_controller") {
if (is_win) {
visibility = [ "//chrome/updater/win/*" ]
allow_circular_includes_from = [ "//chrome/updater:lib" ]
cflags_cc = [ "-Wno-missing-braces" ]
sources = [ "app_install_controller.cc" ]
deps = [
":install_progress_observer",
":lib",
"//base",
"//base:i18n",
"//chrome/updater:base",
"//chrome/updater:lib",
"//chrome/updater:version_header",
"//chrome/updater/win/ui",
]
}
}
source_set("updater_tests") { source_set("updater_tests") {
testonly = true testonly = true
...@@ -149,11 +176,11 @@ source_set("updater_tests") { ...@@ -149,11 +176,11 @@ source_set("updater_tests") {
] ]
deps = [ deps = [
":app_install_controller",
":constants", ":constants",
":lib", ":lib",
":tag_extractor", ":tag_extractor",
"//base/test:test_support", "//base/test:test_support",
"//chrome/updater:app_install",
"//testing/gtest", "//testing/gtest",
"//url:url", "//url:url",
] ]
...@@ -183,10 +210,10 @@ test("updater_unittests") { ...@@ -183,10 +210,10 @@ test("updater_unittests") {
] ]
deps = [ deps = [
":app_install_controller",
":lib", ":lib",
"//base", "//base",
"//base/test:test_support", "//base/test:test_support",
"//chrome/updater:app_install",
"//chrome/updater:version_header", "//chrome/updater:version_header",
"//chrome/updater/win/test:test_executables", "//chrome/updater/win/test:test_executables",
"//chrome/updater/win/test:test_strings", "//chrome/updater/win/test:test_strings",
......
...@@ -6,63 +6,42 @@ ...@@ -6,63 +6,42 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <utility>
#include <vector> #include <vector>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/callback_forward.h" #include "base/check.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/i18n/icu_util.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/message_loop/message_pump_type.h"
#include "base/run_loop.h"
#include "base/sequence_checker.h" #include "base/sequence_checker.h"
#include "base/sequenced_task_runner.h" #include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h" #include "base/task/post_task.h"
#include "base/task/single_thread_task_executor.h"
#include "base/task/single_thread_task_runner_thread_mode.h"
#include "base/task/task_traits.h" #include "base/task/task_traits.h"
#include "base/task/thread_pool.h" #include "base/task/thread_pool.h"
#include "base/threading/sequenced_task_runner_handle.h" #include "base/threading/sequenced_task_runner_handle.h"
#include "base/threading/thread_checker.h" #include "base/threading/thread_checker.h"
#include "base/threading/thread_restrictions.h" #include "base/threading/thread_restrictions.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "base/version.h" #include "base/time/time.h"
#include "base/win/atl.h" #include "base/win/atl.h"
#include "chrome/updater/app/app.h"
#include "chrome/updater/configurator.h"
#include "chrome/updater/constants.h"
#include "chrome/updater/control_service.h" #include "chrome/updater/control_service.h"
#include "chrome/updater/installer.h"
#include "chrome/updater/persisted_data.h"
#include "chrome/updater/prefs.h"
#include "chrome/updater/update_service.h" #include "chrome/updater/update_service.h"
#include "chrome/updater/updater_version.h"
#include "chrome/updater/win/install_progress_observer.h" #include "chrome/updater/win/install_progress_observer.h"
#include "chrome/updater/win/setup/setup.h"
#include "chrome/updater/win/ui/progress_wnd.h" #include "chrome/updater/win/ui/progress_wnd.h"
#include "chrome/updater/win/ui/resources/resources.grh" #include "chrome/updater/win/ui/resources/resources.grh"
#include "chrome/updater/win/ui/splash_screen.h" #include "chrome/updater/win/ui/splash_screen.h"
#include "chrome/updater/win/ui/util.h" #include "chrome/updater/win/ui/util.h"
#include "chrome/updater/win/util.h" #include "chrome/updater/win/util.h"
#include "components/prefs/pref_service.h"
namespace updater { namespace updater {
namespace { namespace {
// TODO(sorin): remove the hardcoding of the application name. // TODO(sorin): remove the hardcoding of the application name.
// https://crbug.com/1014298 // https://crbug.com/1065588
constexpr base::char16 kAppNameChrome[] = L"Google Chrome"; constexpr base::char16 kAppNameChrome[] = L"Google Chrome";
class AppInstallController;
// Implements a simple inter-thread communication protocol based on Windows // Implements a simple inter-thread communication protocol based on Windows
// messages exchanged between the application installer and its UI. // messages exchanged between the application installer and its UI.
// //
...@@ -80,7 +59,10 @@ class InstallProgressObserverIPC : public InstallProgressObserver { ...@@ -80,7 +59,10 @@ class InstallProgressObserverIPC : public InstallProgressObserver {
static constexpr unsigned int WM_PROGRESS_WINDOW_IPC = WM_APP + 1; static constexpr unsigned int WM_PROGRESS_WINDOW_IPC = WM_APP + 1;
explicit InstallProgressObserverIPC(ui::ProgressWnd* progress_wnd); explicit InstallProgressObserverIPC(ui::ProgressWnd* progress_wnd);
~InstallProgressObserverIPC() override; InstallProgressObserverIPC(const InstallProgressObserverIPC&) = delete;
InstallProgressObserverIPC& operator=(const InstallProgressObserverIPC&) =
delete;
~InstallProgressObserverIPC() override = default;
// Called by the window proc when a specific application message is processed // Called by the window proc when a specific application message is processed
// by the progress window. This call always occurs in the context of the // by the progress window. This call always occurs in the context of the
...@@ -126,7 +108,7 @@ class InstallProgressObserverIPC : public InstallProgressObserver { ...@@ -126,7 +108,7 @@ class InstallProgressObserverIPC : public InstallProgressObserver {
}; };
struct ParamOnUpdateAvailable { struct ParamOnUpdateAvailable {
ParamOnUpdateAvailable(); ParamOnUpdateAvailable() = default;
ParamOnUpdateAvailable(const ParamOnUpdateAvailable&) = delete; ParamOnUpdateAvailable(const ParamOnUpdateAvailable&) = delete;
ParamOnUpdateAvailable& operator=(const ParamOnUpdateAvailable&) = delete; ParamOnUpdateAvailable& operator=(const ParamOnUpdateAvailable&) = delete;
...@@ -136,7 +118,7 @@ class InstallProgressObserverIPC : public InstallProgressObserver { ...@@ -136,7 +118,7 @@ class InstallProgressObserverIPC : public InstallProgressObserver {
}; };
struct ParamOnDownloading { struct ParamOnDownloading {
ParamOnDownloading(); ParamOnDownloading() = default;
ParamOnDownloading(const ParamOnDownloading&) = delete; ParamOnDownloading(const ParamOnDownloading&) = delete;
ParamOnDownloading& operator=(const ParamOnDownloading&) = delete; ParamOnDownloading& operator=(const ParamOnDownloading&) = delete;
...@@ -147,7 +129,7 @@ class InstallProgressObserverIPC : public InstallProgressObserver { ...@@ -147,7 +129,7 @@ class InstallProgressObserverIPC : public InstallProgressObserver {
}; };
struct ParamOnWaitingToInstall { struct ParamOnWaitingToInstall {
ParamOnWaitingToInstall(); ParamOnWaitingToInstall() = default;
ParamOnWaitingToInstall(const ParamOnWaitingToInstall&) = delete; ParamOnWaitingToInstall(const ParamOnWaitingToInstall&) = delete;
ParamOnWaitingToInstall& operator=(const ParamOnWaitingToInstall&) = delete; ParamOnWaitingToInstall& operator=(const ParamOnWaitingToInstall&) = delete;
...@@ -156,7 +138,7 @@ class InstallProgressObserverIPC : public InstallProgressObserver { ...@@ -156,7 +138,7 @@ class InstallProgressObserverIPC : public InstallProgressObserver {
}; };
struct ParamOnInstalling { struct ParamOnInstalling {
ParamOnInstalling(); ParamOnInstalling() = default;
ParamOnInstalling(const ParamOnInstalling&) = delete; ParamOnInstalling(const ParamOnInstalling&) = delete;
ParamOnInstalling& operator=(const ParamOnInstalling&) = delete; ParamOnInstalling& operator=(const ParamOnInstalling&) = delete;
...@@ -167,7 +149,7 @@ class InstallProgressObserverIPC : public InstallProgressObserver { ...@@ -167,7 +149,7 @@ class InstallProgressObserverIPC : public InstallProgressObserver {
}; };
struct ParamOnComplete { struct ParamOnComplete {
ParamOnComplete(); ParamOnComplete() = default;
ParamOnComplete(const ParamOnComplete&) = delete; ParamOnComplete(const ParamOnComplete&) = delete;
ParamOnComplete& operator=(const ParamOnComplete&) = delete; ParamOnComplete& operator=(const ParamOnComplete&) = delete;
...@@ -181,20 +163,8 @@ class InstallProgressObserverIPC : public InstallProgressObserver { ...@@ -181,20 +163,8 @@ class InstallProgressObserverIPC : public InstallProgressObserver {
// The thread id of the thread which owns the |ProgressWnd|. // The thread id of the thread which owns the |ProgressWnd|.
int window_thread_id_ = 0; int window_thread_id_ = 0;
InstallProgressObserverIPC(const InstallProgressObserverIPC&) = delete;
InstallProgressObserverIPC& operator=(const InstallProgressObserverIPC&) =
delete;
}; };
InstallProgressObserverIPC::ParamOnUpdateAvailable::ParamOnUpdateAvailable() =
default;
InstallProgressObserverIPC::ParamOnDownloading::ParamOnDownloading() = default;
InstallProgressObserverIPC::ParamOnWaitingToInstall::ParamOnWaitingToInstall() =
default;
InstallProgressObserverIPC::ParamOnInstalling::ParamOnInstalling() = default;
InstallProgressObserverIPC::ParamOnComplete::ParamOnComplete() = default;
InstallProgressObserverIPC::InstallProgressObserverIPC( InstallProgressObserverIPC::InstallProgressObserverIPC(
ui::ProgressWnd* progress_wnd) ui::ProgressWnd* progress_wnd)
: progress_wnd_(progress_wnd), : progress_wnd_(progress_wnd),
...@@ -204,7 +174,6 @@ InstallProgressObserverIPC::InstallProgressObserverIPC( ...@@ -204,7 +174,6 @@ InstallProgressObserverIPC::InstallProgressObserverIPC(
DCHECK(progress_wnd->m_hWnd); DCHECK(progress_wnd->m_hWnd);
DCHECK(IsWindow(progress_wnd->m_hWnd)); DCHECK(IsWindow(progress_wnd->m_hWnd));
} }
InstallProgressObserverIPC::~InstallProgressObserverIPC() = default;
void InstallProgressObserverIPC::OnCheckingForUpdate() { void InstallProgressObserverIPC::OnCheckingForUpdate() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
...@@ -388,38 +357,36 @@ void InstallProgressObserverIPC::Invoke(WPARAM wparam, LPARAM lparam) { ...@@ -388,38 +357,36 @@ void InstallProgressObserverIPC::Invoke(WPARAM wparam, LPARAM lparam) {
// posts a reply to the main thread, which makes the main thread exit its run // posts a reply to the main thread, which makes the main thread exit its run
// loop, and then the main thread returns to the destructor of this class, // loop, and then the main thread returns to the destructor of this class,
// and destructs its class members. // and destructs its class members.
class AppInstallController class AppInstallControllerImpl : public AppInstallController,
: public base::RefCountedThreadSafe<AppInstallController>,
public ui::ProgressWndEvents, public ui::ProgressWndEvents,
public WTL::CMessageFilter { public WTL::CMessageFilter {
public: public:
AppInstallController(); AppInstallControllerImpl();
AppInstallController(const AppInstallController&) = delete; AppInstallControllerImpl(const AppInstallControllerImpl&) = delete;
AppInstallController& operator=(const AppInstallController&) = delete; AppInstallControllerImpl& operator=(const AppInstallControllerImpl&) = delete;
// Override for AppInstallController.
void InstallApp(const std::string& app_id, void InstallApp(const std::string& app_id,
base::OnceCallback<void(int)> callback); base::OnceCallback<void(int)> callback) override;
private: private:
friend class base::RefCountedThreadSafe<AppInstallController>; friend class base::RefCountedThreadSafe<AppInstallControllerImpl>;
~AppInstallController() override; ~AppInstallControllerImpl() override;
// Overrides for OmahaWndEvents. These functions are called on the UI thread. // Overrides for OmahaWndEvents. These functions are called on the UI thread.
void DoClose() override {} void DoClose() override {}
void DoExit() override; void DoExit() override;
// Overrides for CompleteWndEvents. This function is called on the UI thread. // Overrides for CompleteWndEvents. This function is called on the UI thread.
bool DoLaunchBrowser(const base::string16& url) override { return false; } bool DoLaunchBrowser(const base::string16& url) override;
// Overrides for ProgressWndEvents. These functions are called on the UI // Overrides for ProgressWndEvents. These functions are called on the UI
// thread. // thread.
bool DoRestartBrowser(bool restart_all_browsers, bool DoRestartBrowser(bool restart_all_browsers,
const std::vector<base::string16>& urls) override { const std::vector<base::string16>& urls) override;
return false; bool DoReboot() override;
}
bool DoReboot() override { return false; }
void DoCancel() override {} void DoCancel() override {}
// Overrides for WTL::CMessageFilter. // Overrides for WTL::CMessageFilter.
...@@ -473,16 +440,17 @@ class AppInstallController ...@@ -473,16 +440,17 @@ class AppInstallController
// TODO(sorin): fix the hardcoding of the application name. // TODO(sorin): fix the hardcoding of the application name.
// https:crbug.com/1014298 // https:crbug.com/1014298
AppInstallController::AppInstallController() AppInstallControllerImpl::AppInstallControllerImpl()
: main_task_runner_(base::SequencedTaskRunnerHandle::Get()), : main_task_runner_(base::SequencedTaskRunnerHandle::Get()),
ui_task_runner_(base::ThreadPool::CreateSingleThreadTaskRunner( ui_task_runner_(base::ThreadPool::CreateSingleThreadTaskRunner(
{base::TaskPriority::USER_BLOCKING, {base::TaskPriority::USER_BLOCKING,
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
base::SingleThreadTaskRunnerThreadMode::DEDICATED)), base::SingleThreadTaskRunnerThreadMode::DEDICATED)),
app_name_(kAppNameChrome) {} app_name_(kAppNameChrome) {}
AppInstallController::~AppInstallController() = default; AppInstallControllerImpl::~AppInstallControllerImpl() = default;
void AppInstallController::InstallApp(const std::string& app_id, void AppInstallControllerImpl::InstallApp(
const std::string& app_id,
base::OnceCallback<void(int)> callback) { base::OnceCallback<void(int)> callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(base::ThreadTaskRunnerHandle::IsSet()); DCHECK(base::ThreadTaskRunnerHandle::IsSet());
...@@ -491,19 +459,19 @@ void AppInstallController::InstallApp(const std::string& app_id, ...@@ -491,19 +459,19 @@ void AppInstallController::InstallApp(const std::string& app_id,
callback_ = std::move(callback); callback_ = std::move(callback);
ui_task_runner_->PostTaskAndReply( ui_task_runner_->PostTaskAndReply(
FROM_HERE, base::BindOnce(&AppInstallController::InitializeUI, this), FROM_HERE, base::BindOnce(&AppInstallControllerImpl::InitializeUI, this),
base::BindOnce(&AppInstallController::DoInstallApp, this)); base::BindOnce(&AppInstallControllerImpl::DoInstallApp, this));
} }
void AppInstallController::DoInstallApp() { void AppInstallControllerImpl::DoInstallApp() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// At this point, the UI has been initialized, which means the UI can be // At this point, the UI has been initialized, which means the UI can be
// used from now on as an observer of the application install. The task // used from now on as an observer of the application install. The task
// below runs the UI message loop for the UI until it exits, because // below runs the UI message loop for the UI until it exits, because
// a WM_QUIT message has been posted to it. // a WM_QUIT message has been posted to it.
ui_task_runner_->PostTask(FROM_HERE, ui_task_runner_->PostTask(
base::BindOnce(&AppInstallController::RunUI, this)); FROM_HERE, base::BindOnce(&AppInstallControllerImpl::RunUI, this));
update_service_ = CreateUpdateService(); update_service_ = CreateUpdateService();
...@@ -512,19 +480,19 @@ void AppInstallController::DoInstallApp() { ...@@ -512,19 +480,19 @@ void AppInstallController::DoInstallApp() {
update_service_->Update( update_service_->Update(
app_id_, UpdateService::Priority::kForeground, app_id_, UpdateService::Priority::kForeground,
base::BindRepeating(&AppInstallController::StateChange, this), base::BindRepeating(&AppInstallControllerImpl::StateChange, this),
base::BindOnce(&AppInstallController::InstallComplete, this)); base::BindOnce(&AppInstallControllerImpl::InstallComplete, this));
} }
// TODO(crbug.com/1116492) - handle the case when this callback is posted // TODO(crbug.com/1116492) - handle the case when this callback is posted
// and no other |StateChange| callbacks were received. Since UI is driven by // and no other |StateChange| callbacks were received. Since UI is driven by
// state changes only, then the UI is not going to close in this case. // state changes only, then the UI is not going to close in this case.
void AppInstallController::InstallComplete(UpdateService::Result result) { void AppInstallControllerImpl::InstallComplete(UpdateService::Result result) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
update_service_ = nullptr; update_service_ = nullptr;
} }
void AppInstallController::StateChange( void AppInstallControllerImpl::StateChange(
UpdateService::UpdateState update_state) { UpdateService::UpdateState update_state) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(install_progress_observer_ipc_); DCHECK(install_progress_observer_ipc_);
...@@ -575,7 +543,7 @@ void AppInstallController::StateChange( ...@@ -575,7 +543,7 @@ void AppInstallController::StateChange(
} }
} }
void AppInstallController::HandleInstallResult( void AppInstallControllerImpl::HandleInstallResult(
const UpdateService::UpdateState& update_state) { const UpdateService::UpdateState& update_state) {
CompletionCodes completion_code = CompletionCodes::COMPLETION_CODE_ERROR; CompletionCodes completion_code = CompletionCodes::COMPLETION_CODE_ERROR;
base::string16 completion_text; base::string16 completion_text;
...@@ -613,7 +581,7 @@ void AppInstallController::HandleInstallResult( ...@@ -613,7 +581,7 @@ void AppInstallController::HandleInstallResult(
// Creates and shows the progress window. The window has thread affinity. It // Creates and shows the progress window. The window has thread affinity. It
// must be created, process its messages, and be destroyed on the same thread. // must be created, process its messages, and be destroyed on the same thread.
void AppInstallController::InitializeUI() { void AppInstallControllerImpl::InitializeUI() {
DCHECK(ui_task_runner_->RunsTasksInCurrentSequence()); DCHECK(ui_task_runner_->RunsTasksInCurrentSequence());
base::ScopedDisallowBlocking no_blocking_allowed_on_ui_thread; base::ScopedDisallowBlocking no_blocking_allowed_on_ui_thread;
...@@ -627,7 +595,7 @@ void AppInstallController::InitializeUI() { ...@@ -627,7 +595,7 @@ void AppInstallController::InitializeUI() {
progress_wnd_->Show(); progress_wnd_->Show();
} }
void AppInstallController::RunUI() { void AppInstallControllerImpl::RunUI() {
DCHECK(ui_task_runner_->RunsTasksInCurrentSequence()); DCHECK(ui_task_runner_->RunsTasksInCurrentSequence());
DCHECK_EQ(GetUIThreadID(), GetCurrentThreadId()); DCHECK_EQ(GetUIThreadID(), GetCurrentThreadId());
...@@ -641,12 +609,12 @@ void AppInstallController::RunUI() { ...@@ -641,12 +609,12 @@ void AppInstallController::RunUI() {
base::BindOnce(std::move(callback_), 0)); base::BindOnce(std::move(callback_), 0));
} }
void AppInstallController::DoExit() { void AppInstallControllerImpl::DoExit() {
DCHECK_EQ(GetUIThreadID(), GetCurrentThreadId()); DCHECK_EQ(GetUIThreadID(), GetCurrentThreadId());
PostThreadMessage(GetCurrentThreadId(), WM_QUIT, 0, 0); PostThreadMessage(GetCurrentThreadId(), WM_QUIT, 0, 0);
} }
BOOL AppInstallController::PreTranslateMessage(MSG* msg) { BOOL AppInstallControllerImpl::PreTranslateMessage(MSG* msg) {
DCHECK_EQ(GetUIThreadID(), GetCurrentThreadId()); DCHECK_EQ(GetUIThreadID(), GetCurrentThreadId());
if (msg->message == InstallProgressObserverIPC::WM_PROGRESS_WINDOW_IPC) { if (msg->message == InstallProgressObserverIPC::WM_PROGRESS_WINDOW_IPC) {
install_progress_observer_ipc_->Invoke(msg->wParam, msg->lParam); install_progress_observer_ipc_->Invoke(msg->wParam, msg->lParam);
...@@ -655,145 +623,38 @@ BOOL AppInstallController::PreTranslateMessage(MSG* msg) { ...@@ -655,145 +623,38 @@ BOOL AppInstallController::PreTranslateMessage(MSG* msg) {
return false; return false;
} }
DWORD AppInstallController::GetUIThreadID() const { DWORD AppInstallControllerImpl::GetUIThreadID() const {
DCHECK(progress_wnd_); DCHECK(progress_wnd_);
return ::GetWindowThreadProcessId(progress_wnd_->m_hWnd, nullptr); return ::GetWindowThreadProcessId(progress_wnd_->m_hWnd, nullptr);
} }
} // namespace bool AppInstallControllerImpl::DoLaunchBrowser(const base::string16& url) {
DCHECK_EQ(GetUIThreadID(), GetCurrentThreadId());
// Sets the updater up, shows up a splash screen, then installs an application return false;
// while displaying the UI progress window.
class AppInstall : public App {
public:
AppInstall() = default;
private:
~AppInstall() override = default;
// Overrides for App.
void Initialize() override;
void FirstTaskRun() override;
void SetupDone(int result);
// Handles the --app-id command line argument, and triggers installing of the
// corresponding app-id if the argument is present.
void HandleAppId();
// Makes this version of the updater active, self-registers for updates, then
// runs the |done| closure.
void MakeActive(base::OnceClosure done);
// Bound to the main sequence.
SEQUENCE_CHECKER(sequence_checker_);
scoped_refptr<AppInstallController> app_install_controller_;
// The splash screen has a fading effect. That means that the splash screen
// needs to be alive for a while, until the fading effect is over.
std::unique_ptr<ui::SplashScreen> splash_screen_;
// These prefs objects are used to make the updater active and register this
// version of the updater for self-updates.
//
// TODO(crbug.com/1109231) - this is a temporary workaround until a better
// fix is found.
std::unique_ptr<LocalPrefs> local_prefs_;
std::unique_ptr<GlobalPrefs> global_prefs_;
scoped_refptr<base::TaskRunner> make_active_task_runner_;
};
void AppInstall::Initialize() {
base::i18n::InitializeICU();
// Creating |global_prefs_| requires acquiring a global lock, and this lock is
// typical owned by the RPC server. That means that if the server is
// running, the following code will block, and the install will not proceed
// until the server releases the lock.
global_prefs_ = CreateGlobalPrefs();
local_prefs_ = CreateLocalPrefs();
}
void AppInstall::FirstTaskRun() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(base::ThreadTaskRunnerHandle::IsSet());
splash_screen_ = std::make_unique<ui::SplashScreen>(kAppNameChrome);
splash_screen_->Show();
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE,
{base::MayBlock(), base::TaskPriority::USER_BLOCKING,
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
base::BindOnce([]() { return Setup(false); }),
base::BindOnce(
[](ui::SplashScreen* splash_screen,
base::OnceCallback<void(int)> done, int result) {
splash_screen->Dismiss(base::BindOnce(std::move(done), result));
},
splash_screen_.get(), base::BindOnce(&AppInstall::SetupDone, this)));
} }
// Updates the prefs if the setup is successful, then continue installing bool AppInstallControllerImpl::DoRestartBrowser(
// the application if --appid is specified on the command line. bool restart_all_browsers,
void AppInstall::SetupDone(int result) { const std::vector<base::string16>& urls) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_EQ(GetUIThreadID(), GetCurrentThreadId());
return false;
if (result != 0) {
Shutdown(result);
return;
}
// Invoke |HandleAppId| to continue the execution flow.
MakeActive(base::BindOnce(&AppInstall::HandleAppId, this));
} }
void AppInstall::HandleAppId() { bool AppInstallControllerImpl::DoReboot() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_EQ(GetUIThreadID(), GetCurrentThreadId());
return false;
// This releases the prefs lock, and the RPC server can be started.
global_prefs_ = nullptr;
local_prefs_ = nullptr;
// If no app id is provided, then invoke ControlService::Run to wake
// this version of the updater, to do an update check, and possibly promote
// it as a result.
const std::string app_id =
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(kAppIdSwitch);
if (app_id.empty()) {
// The instance of |CreateControlService| has sequence affinity. Bind it
// in the closure to ensure it is released in this sequence.
scoped_refptr<ControlService> control_service = CreateControlService();
control_service->Run(base::BindOnce(
[](scoped_refptr<ControlService> /*control_service*/,
scoped_refptr<AppInstall> app_install) { app_install->Shutdown(0); },
control_service, base::WrapRefCounted(this)));
return;
}
app_install_controller_ = base::MakeRefCounted<AppInstallController>();
app_install_controller_->InstallApp(
app_id, base::BindOnce(&AppInstall::Shutdown, this));
} }
// TODO(crbug.com/1109231) - this is a temporary workaround. } // namespace
void AppInstall::MakeActive(base::OnceClosure done) {
local_prefs_->SetQualified(true);
local_prefs_->GetPrefService()->CommitPendingWrite(base::BindOnce(
[](base::OnceClosure done, PrefService* pref_service) {
DCHECK(pref_service);
auto persisted_data = base::MakeRefCounted<PersistedData>(pref_service);
persisted_data->SetProductVersion(
kUpdaterAppId, base::Version(UPDATER_VERSION_STRING));
pref_service->CommitPendingWrite(std::move(done));
},
std::move(done), global_prefs_->GetPrefService()));
}
scoped_refptr<App> MakeAppInstall() { scoped_refptr<App> MakeAppInstall() {
return base::MakeRefCounted<AppInstall>(); return base::MakeRefCounted<AppInstall>(
base::BindRepeating([]() -> std::unique_ptr<SplashScreen> {
return std::make_unique<ui::SplashScreen>(kAppNameChrome);
}),
base::BindRepeating([]() -> scoped_refptr<AppInstallController> {
return base::MakeRefCounted<AppInstallControllerImpl>();
}));
} }
} // namespace updater } // namespace updater
...@@ -25,8 +25,8 @@ source_set("test_common") { ...@@ -25,8 +25,8 @@ source_set("test_common") {
deps = [ deps = [
"//base", "//base",
"//chrome/updater:app_install",
"//chrome/updater:base", "//chrome/updater:base",
"//chrome/updater/win:app_install_controller",
"//chrome/updater/win:lib", "//chrome/updater/win:lib",
] ]
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/threading/thread_checker.h" #include "base/threading/thread_checker.h"
#include "base/win/atl.h" #include "base/win/atl.h"
#include "base/win/scoped_gdi_object.h" #include "base/win/scoped_gdi_object.h"
#include "chrome/updater/splash_screen.h"
#include "chrome/updater/win/ui/owner_draw_controls.h" #include "chrome/updater/win/ui/owner_draw_controls.h"
#include "chrome/updater/win/ui/resources/resources.grh" #include "chrome/updater/win/ui/resources/resources.grh"
...@@ -19,8 +20,9 @@ namespace updater { ...@@ -19,8 +20,9 @@ namespace updater {
namespace ui { namespace ui {
class SplashScreen : public CAxDialogImpl<SplashScreen>, class SplashScreen : public CAxDialogImpl<SplashScreen>,
public CustomDlgColors,
public OwnerDrawTitleBar, public OwnerDrawTitleBar,
public CustomDlgColors { public updater::SplashScreen {
public: public:
static constexpr int IDD = IDD_PROGRESS; static constexpr int IDD = IDD_PROGRESS;
...@@ -29,10 +31,9 @@ class SplashScreen : public CAxDialogImpl<SplashScreen>, ...@@ -29,10 +31,9 @@ class SplashScreen : public CAxDialogImpl<SplashScreen>,
SplashScreen& operator=(const SplashScreen&) = delete; SplashScreen& operator=(const SplashScreen&) = delete;
~SplashScreen() override; ~SplashScreen() override;
void Show(); // Overrides for SplashScreen.
void Show() override;
// Does alpha blending and closese the window. void Dismiss(base::OnceClosure on_close_closure) override;
void Dismiss(base::OnceClosure on_close_closure);
BEGIN_MSG_MAP(SplashScreen) BEGIN_MSG_MAP(SplashScreen)
MESSAGE_HANDLER(WM_TIMER, OnTimer) MESSAGE_HANDLER(WM_TIMER, OnTimer)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment