Commit 3e3058ab authored by Mila Green's avatar Mila Green Committed by Commit Bot

Updater: Add register command switch.

Since on macOS there is no meta installer, the flow to installing an updater is the following:
1. Chrome (or other app) is drag installed.
2. It tries to register itself with the updater.
   It does that by running its bundled updater, with the
   --register --app-id=... --version=... command.
   This is done over RPC, so if there is an updater on the system, it will get the call.
   If registration is successful, no other action is needed.
3. If no updater is present, the bundled updater will:
   3.1. Install itself
   3.2. "wake" itself, so that it is promoted.
   3.3. Register itself for updates
   3.4. Register the app (Chrome, etc.) for updates.

Bug: 1109231
Change-Id: I6e3f31ffbb6eaa6334bd9caa708b3b37f883d674
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2350191
Commit-Queue: Mila Green <milagreen@chromium.org>
Reviewed-by: default avatarJoshua Pawlicki <waffles@chromium.org>
Cr-Commit-Position: refs/heads/master@{#802261}
parent a22b9616
......@@ -83,10 +83,14 @@ if (is_win || is_mac) {
sources = [
"app/app.cc",
"app/app.h",
"app/app_register.cc",
"app/app_register.h",
"app/app_server.cc",
"app/app_server.h",
"app/app_uninstall.cc",
"app/app_uninstall.h",
"app/app_update.cc",
"app/app_update.h",
"app/app_wake.cc",
"app/app_wake.h",
"configurator.cc",
......@@ -103,6 +107,7 @@ if (is_win || is_mac) {
"prefs.cc",
"prefs.h",
"prefs_impl.h",
"setup.h",
"tag.cc",
"tag.h",
"update_service_in_process.cc",
......@@ -130,6 +135,7 @@ if (is_win || is_mac) {
"mac/update_service_out_of_process.mm",
"prefs_mac.mm",
"service_factory_mac.mm",
"setup_mac.cc",
]
}
......@@ -148,6 +154,7 @@ if (is_win || is_mac) {
"lib_util_win.cc",
"prefs_win.cc",
"service_factory_win.cc",
"setup_win.cc",
]
}
......@@ -225,10 +232,6 @@ if (is_win || is_mac) {
source_set("app_install") {
sources = [ "app/app_install.h" ]
if (is_mac) {
sources += [ "mac/setup/app_install.cc" ]
}
if (is_win) {
sources += [ "win/app_install.cc" ]
}
......@@ -309,6 +312,7 @@ if (is_win || is_mac) {
"//chrome/common:constants",
"//chrome/updater/device_management:unittest",
"//chrome/updater/test/test_app",
"//chrome/updater/test/test_app:version_header",
"//chrome/updater/tools:unittest",
"//components/prefs:test_support",
"//components/update_client",
......@@ -341,6 +345,8 @@ if (is_win || is_mac) {
"mac/scoped_xpc_service_mock.mm",
"mac/update_service_out_of_process_test.mm",
"test/integration_tests_mac.mm",
"test/test_app/constants.cc",
"test/test_app/constants.h",
]
deps += [
......@@ -355,7 +361,10 @@ if (is_win || is_mac) {
"//third_party/ocmock",
]
data_deps = [ "//chrome/updater/mac:updater_bundle" ]
data_deps = [
"//chrome/updater/mac:updater_bundle",
"//chrome/updater/test/test_app:test_app",
]
}
}
}
// 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_register.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
#include "base/sequence_checker.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/time/time.h"
#include "base/version.h"
#include "chrome/updater/app/app.h"
#include "chrome/updater/app/server/mac/server.h"
#include "chrome/updater/constants.h"
#include "chrome/updater/control_service.h"
#include "chrome/updater/persisted_data.h"
#include "chrome/updater/registration_data.h"
#include "chrome/updater/setup.h"
#include "chrome/updater/update_service.h"
#include "chrome/updater/updater_version.h"
namespace updater {
namespace {
// This delay is needed to avoid a race condition with launchctl.
constexpr base::TimeDelta kRPCDelay = base::TimeDelta::FromSeconds(2);
constexpr int kBadArgumentsExitCode = -100;
} // namespace
class AppRegister : public App {
private:
~AppRegister() override = default;
// Overrides for App.
void Uninitialize() override;
void FirstTaskRun() override;
using RegisterCallback =
base::OnceCallback<void(const RegistrationResponse&)>;
void InstallCandidateDone(int result);
void WakeCandidate();
void ControlServiceRunDone(int result);
void RegisterAppDone(const RegistrationResponse& response);
void RegisterUpdaterDone(const RegistrationResponse& response);
void RegisterAppAfterPromotionDone(const RegistrationResponse& response);
void RegisterUpdater(RegisterCallback callback);
void RegisterApp(RegisterCallback callback);
void RegisterAppHelper(RegistrationRequest request,
RegisterCallback callback);
void ResetControlService();
void ResetUpdateService();
SEQUENCE_CHECKER(sequence_checker_);
scoped_refptr<UpdateService> update_service_;
scoped_refptr<ControlService> control_service_;
};
void AppRegister::Uninitialize() {
ResetUpdateService();
ResetControlService();
}
void AppRegister::FirstTaskRun() {
RegisterApp(base::BindOnce(&AppRegister::RegisterAppDone, this));
}
void AppRegister::ResetControlService() {
if (control_service_) {
control_service_->Uninitialize();
control_service_ = nullptr;
}
}
void AppRegister::ResetUpdateService() {
if (update_service_) {
update_service_->Uninitialize();
update_service_ = nullptr;
}
}
void AppRegister::RegisterAppHelper(RegistrationRequest request,
RegisterCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
ResetUpdateService();
update_service_ = CreateUpdateService();
base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&UpdateService::RegisterApp, update_service_,
request, std::move(callback)));
}
void AppRegister::RegisterApp(RegisterCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
const base::CommandLine& command_line =
*base::CommandLine::ForCurrentProcess();
if (!command_line.HasSwitch(kAppIdSwitch) ||
!command_line.HasSwitch(kAppVersionSwitch)) {
LOG(ERROR) << "Command line is missing the app-id or app-version switch.";
Shutdown(kBadArgumentsExitCode);
return;
}
RegistrationRequest request;
request.app_id = command_line.GetSwitchValueASCII(kAppIdSwitch);
const std::string commandLineVersion =
command_line.GetSwitchValueASCII(kAppVersionSwitch);
const base::Version version = base::Version(commandLineVersion);
if (!version.IsValid()) {
LOG(ERROR) << "Invalid version: " << commandLineVersion;
Shutdown(kBadArgumentsExitCode);
return;
}
request.version = version;
RegisterAppHelper(request, std::move(callback));
}
void AppRegister::RegisterAppDone(const RegistrationResponse& response) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
VLOG(1) << __func__ << ". Response: " << response.status_code;
if (response.status_code == 0) {
Shutdown(0);
return;
}
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, {base::MayBlock()}, base::BindOnce(&InstallCandidate, false),
base::BindOnce(&AppRegister::InstallCandidateDone, this));
}
void AppRegister::InstallCandidateDone(int result) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
VLOG(1) << __func__ << ". Result: " << result;
if (result != 0) {
LOG(ERROR) << __func__ << ". Failed to install candidate. Calling Shutdown("
<< result << ")";
Shutdown(result);
return;
}
base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, base::BindOnce(&AppRegister::WakeCandidate, this), kRPCDelay);
}
void AppRegister::WakeCandidate() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
ResetControlService();
control_service_ = CreateControlService();
control_service_->Run(
base::BindOnce(&AppRegister::ControlServiceRunDone, this, 0));
}
void AppRegister::ControlServiceRunDone(int result) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
VLOG(1) << __func__ << ". Result: " << result;
if (result != 0) {
Shutdown(result);
return;
}
base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::BindOnce(&AppRegister::RegisterUpdater, this,
base::BindOnce(&AppRegister::RegisterUpdaterDone, this)),
kRPCDelay);
}
void AppRegister::RegisterUpdater(RegisterCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
RegistrationRequest request;
request.app_id = kUpdaterAppId;
request.version = base::Version(UPDATER_VERSION_STRING);
RegisterAppHelper(request, std::move(callback));
}
void AppRegister::RegisterUpdaterDone(const RegistrationResponse& response) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
VLOG(1) << __func__ << ". Response: " << response.status_code;
base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::BindOnce(
&AppRegister::RegisterApp, this,
base::BindOnce(&AppRegister::RegisterAppAfterPromotionDone, this)),
kRPCDelay);
}
void AppRegister::RegisterAppAfterPromotionDone(
const RegistrationResponse& response) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
VLOG(1) << __func__ << ". Response: " << response.status_code;
Shutdown(response.status_code);
}
scoped_refptr<App> MakeAppRegister() {
return base::MakeRefCounted<AppRegister>();
}
} // namespace updater
// 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_APP_APP_REGISTER_H_
#define CHROME_UPDATER_APP_APP_REGISTER_H_
#include "base/memory/scoped_refptr.h"
namespace updater {
class App;
scoped_refptr<App> MakeAppRegister();
} // namespace updater
#endif // CHROME_UPDATER_APP_APP_REGISTER_H_
......@@ -2,7 +2,7 @@
// 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 "chrome/updater/app/app_update.h"
#include "base/bind.h"
#include "base/memory/ref_counted.h"
......@@ -12,19 +12,17 @@
#include "chrome/updater/app/app.h"
#include "chrome/updater/configurator.h"
#include "chrome/updater/constants.h"
#include "chrome/updater/mac/setup/setup.h"
#include "chrome/updater/persisted_data.h"
#include "chrome/updater/prefs.h"
#include "chrome/updater/registration_data.h"
#include "chrome/updater/setup.h"
#include "chrome/updater/updater_version.h"
namespace updater {
namespace {
class AppInstall : public App {
class AppUpdate : public App {
private:
~AppInstall() override = default;
~AppUpdate() override = default;
void Initialize() override;
void Uninitialize() override;
void FirstTaskRun() override;
......@@ -34,21 +32,21 @@ class AppInstall : public App {
scoped_refptr<Configurator> config_;
};
void AppInstall::Initialize() {
void AppUpdate::Initialize() {
config_ = base::MakeRefCounted<Configurator>(CreateGlobalPrefs());
}
void AppInstall::Uninitialize() {
void AppUpdate::Uninitialize() {
PrefsCommitPendingWrites(config_->GetPrefService());
}
void AppInstall::FirstTaskRun() {
void AppUpdate::FirstTaskRun() {
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, {base::MayBlock()}, base::BindOnce(&InstallCandidate),
base::BindOnce(&AppInstall::SetupDone, this));
FROM_HERE, {base::MayBlock()}, base::BindOnce(&InstallCandidate, false),
base::BindOnce(&AppUpdate::SetupDone, this));
}
void AppInstall::SetupDone(int result) {
void AppUpdate::SetupDone(int result) {
if (result != 0) {
Shutdown(result);
return;
......@@ -64,10 +62,8 @@ void AppInstall::SetupDone(int result) {
Shutdown(0);
}
} // namespace
scoped_refptr<App> MakeAppInstall() {
return base::MakeRefCounted<AppInstall>();
scoped_refptr<App> MakeAppUpdate() {
return base::MakeRefCounted<AppUpdate>();
}
} // namespace updater
// 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_APP_APP_UPDATE_H_
#define CHROME_UPDATER_APP_APP_UPDATE_H_
#include "base/memory/scoped_refptr.h"
namespace updater {
class App;
scoped_refptr<App> MakeAppUpdate();
} // namespace updater
#endif // CHROME_UPDATER_APP_APP_UPDATE_H_
......@@ -17,6 +17,7 @@ const char kComServiceSwitch[] = "com-service";
const char kCrashMeSwitch[] = "crash-me";
const char kCrashHandlerSwitch[] = "crash-handler";
const char kUpdateSwitch[] = "update";
const char kRegisterSwitch[] = "register";
const char kInstallSwitch[] = "install";
const char kUninstallSwitch[] = "uninstall";
const char kSystemSwitch[] = "system";
......@@ -25,7 +26,8 @@ const char kInitDoneNotifierSwitch[] = "init-done-notifier";
const char kNoRateLimitSwitch[] = "no-rate-limit";
const char kEnableLoggingSwitch[] = "enable-logging";
const char kLoggingModuleSwitch[] = "vmodule";
const char kAppIdSwitch[] = "appid";
const char kAppIdSwitch[] = "app-id";
const char kAppVersionSwitch[] = "app-version";
const char kWakeSwitch[] = "wake";
#if defined(OS_WIN)
......
......@@ -56,6 +56,9 @@ extern const char kCrashHandlerSwitch[];
// Updates the updater.
extern const char kUpdateSwitch[];
// Registers an app with the updater. Installs the bundled updater if needed.
extern const char kRegisterSwitch[];
// Installs the updater.
extern const char kInstallSwitch[];
......@@ -97,6 +100,9 @@ extern const char kLoggingModuleSwitch[];
// Specifies the application that the Updater needs to install.
extern const char kAppIdSwitch[];
// Specifies the version of the application that the updater needs to register.
extern const char kAppVersionSwitch[];
// URLs.
//
// Omaha server end point.
......
......@@ -120,7 +120,8 @@ base::ScopedCFTypeRef<CFDictionaryRef> CreateServiceLaunchdPlist(
@LAUNCH_JOBKEY_LABEL : GetServiceLaunchdLabel(),
@LAUNCH_JOBKEY_PROGRAMARGUMENTS : @[
base::SysUTF8ToNSString(updater_path.value()),
MakeProgramArgument(kServerSwitch)
MakeProgramArgument(kServerSwitch),
@"--vmodule=*/updater/*=2",
],
@LAUNCH_JOBKEY_MACHSERVICES : @{GetServiceMachName() : @YES},
@LAUNCH_JOBKEY_ABANDONPROCESSGROUP : @NO,
......@@ -164,7 +165,8 @@ base::ScopedCFTypeRef<CFDictionaryRef> CreateControlLaunchdPlist(
@LAUNCH_JOBKEY_LABEL : GetControlLaunchdLabel(),
@LAUNCH_JOBKEY_PROGRAMARGUMENTS : @[
base::SysUTF8ToNSString(updater_path.value()),
MakeProgramArgument(kServerSwitch)
MakeProgramArgument(kServerSwitch),
@"--vmodule=*/updater/*=2",
],
@LAUNCH_JOBKEY_MACHSERVICES : @{GetVersionedServiceMachName() : @YES},
@LAUNCH_JOBKEY_ABANDONPROCESSGROUP : @NO,
......
// 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_SETUP_H_
#define CHROME_UPDATER_SETUP_H_
namespace updater {
int InstallCandidate(bool is_machine);
} // namespace updater
#endif // CHROME_UPDATER_SETUP_H_
// 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/mac/setup/setup.h"
#include "chrome/updater/setup.h"
namespace updater {
int InstallCandidate(bool is_machine) {
return InstallCandidate();
}
} // namespace updater
// 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/setup.h"
#include "chrome/updater/win/setup/setup.h"
namespace updater {
int InstallCandidate(bool is_machine) {
return Setup(is_machine);
}
} // namespace updater
......@@ -5,6 +5,7 @@
#include "chrome/updater/test/integration_tests.h"
#include "base/test/task_environment.h"
#include "build/build_config.h"
#include "chrome/updater/prefs.h"
#include "chrome/updater/updater_version.h"
#include "chrome/updater/util.h"
......@@ -66,6 +67,17 @@ TEST_F(IntegrationTest, InstallAndPromote) {
Uninstall();
}
#if defined(OS_MAC)
TEST_F(IntegrationTest, RegisterTestApp) {
RegisterTestApp();
ExpectInstalled();
ExpectQualified();
ExpectActiveVersion(UPDATER_VERSION_STRING);
ExpectActive();
Uninstall();
}
#endif
#endif // !defined(COMPONENT_BUILD)
} // namespace test
......
......@@ -14,33 +14,37 @@ namespace test {
// the test left the updater in an installed or partially installed state.
void Clean();
// Expect that the system is in a clean state, i.e. no updater is installed and
// Expects that the system is in a clean state, i.e. no updater is installed and
// no traces of an updater exist. Should be run at the start and end of each
// test.
void ExpectClean();
// Place the updater into test mode (use local servers and disable CUP).
// Places the updater into test mode (use local servers and disable CUP).
void EnterTestMode();
// Expect that the updater is installed on the system.
// Expects that the updater is installed on the system.
void ExpectInstalled();
// Install the updater.
// Installs the updater.
void Install();
// Expect that the updater is installed on the system and the launchd tasks
// Expects that the updater is installed on the system and the launchd tasks
// are updated correctly.
void ExpectActive();
// Uninstall the updater. If the updater was installed during the test, it
// Uninstalls the updater. If the updater was installed during the test, it
// should be uninstalled before the end of the test to avoid having an actual
// live updater on the machine that ran the test.
void Uninstall();
// Run the wake client and wait for it to exit. Assert that it exits with
// Runs the wake client and wait for it to exit. Assert that it exits with
// |exit_code|. The server should exit a few seconds after.
void RunWake(int exit_code);
// Registers the test app. As a result, the bundled updater is installed,
// promoted and registered.
void RegisterTestApp();
} // namespace test
} // namespace updater
......
......@@ -12,6 +12,8 @@
#include "chrome/common/mac/launchd.h"
#include "chrome/updater/constants.h"
#include "chrome/updater/mac/xpc_service_names.h"
#include "chrome/updater/test/test_app/constants.h"
#include "chrome/updater/test/test_app/test_app_version.h"
#include "chrome/updater/updater_version.h"
#include "chrome/updater/util.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -33,6 +35,17 @@ base::FilePath GetExecutablePath() {
.Append(FILE_PATH_LITERAL(PRODUCT_FULLNAME_STRING));
}
base::FilePath GetTestAppExecutablePath() {
base::FilePath test_executable;
if (!base::PathService::Get(base::FILE_EXE, &test_executable))
return base::FilePath();
return test_executable.DirName()
.Append(FILE_PATH_LITERAL(TEST_APP_FULLNAME_STRING ".App"))
.Append(FILE_PATH_LITERAL("Contents"))
.Append(FILE_PATH_LITERAL("MacOS"))
.Append(FILE_PATH_LITERAL(TEST_APP_FULLNAME_STRING));
}
base::FilePath GetProductPath() {
return base::mac::GetUserLibraryPath()
.AppendASCII(COMPANY_SHORTNAME_STRING)
......@@ -115,7 +128,7 @@ void Install() {
const base::FilePath path = GetExecutablePath();
ASSERT_FALSE(path.empty());
base::CommandLine command_line(path);
command_line.AppendSwitch(kInstallSwitch);
command_line.AppendSwitch(kUpdateSwitch);
int exit_code = -1;
ASSERT_TRUE(Run(command_line, &exit_code));
EXPECT_EQ(0, exit_code);
......@@ -128,6 +141,16 @@ void ExpectActive() {
CopyServiceLaunchdName()));
}
void RegisterTestApp() {
const base::FilePath path = GetTestAppExecutablePath();
ASSERT_FALSE(path.empty());
base::CommandLine command_line(path);
command_line.AppendSwitch(kRegisterUpdaterSwitch);
int exit_code = -1;
ASSERT_TRUE(Run(command_line, &exit_code));
EXPECT_EQ(0, exit_code);
}
void RunWake(int expected_exit_code) {
const base::FilePath path = GetExecutablePath();
ASSERT_FALSE(path.empty());
......
......@@ -7,6 +7,7 @@
namespace updater {
const char kInstallUpdaterSwitch[] = "install-updater";
const char kRegisterUpdaterSwitch[] = "register-updater";
const char kRegisterToUpdaterSwitch[] = "ipc-register";
const char kForegroundUpdateSwitch[] = "ipc-update";
......
......@@ -13,6 +13,9 @@ namespace updater {
// Installs the updater.
extern const char kInstallUpdaterSwitch[];
// On Mac: Tries to register with the updater. Installs the updater if needed.
extern const char kRegisterUpdaterSwitch[];
// Registers the test app to the updater through IPC.
extern const char kRegisterToUpdaterSwitch[];
......
......@@ -97,12 +97,17 @@ void TestApp::ParseCommandLine() {
update_client = UpdateClient::Create();
if (command_line->HasSwitch(kInstallUpdaterSwitch)) {
InstallUpdater();
Shutdown(0);
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, {base::MayBlock()}, base::BindOnce(&InstallUpdater),
base::BindOnce(&TestApp::Shutdown, this));
} else if (command_line->HasSwitch(kRegisterToUpdaterSwitch)) {
Register();
} else if (command_line->HasSwitch(kForegroundUpdateSwitch)) {
DoForegroundUpdate();
} else if (command_line->HasSwitch(kRegisterUpdaterSwitch)) {
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, {base::MayBlock()}, base::BindOnce(&InstallUpdater),
base::BindOnce(&TestApp::Shutdown, this));
} else {
Shutdown(0);
}
......
......@@ -8,7 +8,7 @@
namespace updater {
// Installs the updater.
void InstallUpdater();
int InstallUpdater();
int TestAppMain(int argc, const char** argv);
......
......@@ -14,6 +14,7 @@
#include "base/mac/bundle_locations.h"
#import "base/mac/foundation_util.h"
#include "base/process/launch.h"
#include "chrome/updater/constants.h"
#include "chrome/updater/mac/xpc_service_names.h"
#include "chrome/updater/test/test_app/constants.h"
#include "chrome/updater/test/test_app/test_app_version.h"
......@@ -22,9 +23,6 @@ namespace updater {
namespace {
constexpr char kInstallCommand[] = "install";
constexpr char kSwapAppCommand[] = "swap-updater";
base::FilePath GetUpdaterAppName() {
return base::FilePath(UPDATER_APP_FULLNAME_STRING ".app");
}
......@@ -33,38 +31,9 @@ base::FilePath GetTestAppFrameworkName() {
return base::FilePath(TEST_APP_FULLNAME_STRING " Framework.framework");
}
base::FilePath GetUpdateFolderName() {
return base::FilePath(TEST_APP_COMPANY_NAME_STRING)
.AppendASCII(UPDATER_APP_FULLNAME_STRING);
}
base::FilePath GetUpdaterAppExecutablePath() {
return base::FilePath("Contents/MacOS")
.AppendASCII(UPDATER_APP_FULLNAME_STRING);
}
void SwapUpdater(const base::FilePath& updater_bundle_path) {
base::FilePath updater_executable_path =
base::mac::GetUserLibraryPath()
.Append(GetUpdateFolderName())
.Append(GetUpdaterAppName())
.Append(GetUpdaterAppExecutablePath());
base::CommandLine swap_command(updater_executable_path);
swap_command.AppendSwitch(kSwapAppCommand);
std::string output;
int exit_code = 0;
base::GetAppOutputWithExitCode(swap_command, &output, &exit_code);
if (exit_code != 0) {
LOG(ERROR) << "Couldn't swap the updater. Exit code: " << exit_code;
}
}
} // namespace
void InstallUpdater() {
int InstallUpdater() {
// The updater executable is in
// C.app/Contents/Frameworks/C.framework/Versions/V/Helpers/CUpdater.app.
base::FilePath updater_bundle_path =
......@@ -78,8 +47,9 @@ void InstallUpdater() {
.Append(GetUpdaterAppName());
if (!base::PathExists(updater_bundle_path)) {
LOG(ERROR) << "Path to the updater app does not exist!";
return;
LOG(ERROR) << "Path to the updater app does not exist! path: "
<< updater_bundle_path;
return -1;
}
base::FilePath updater_executable_path =
......@@ -89,11 +59,14 @@ void InstallUpdater() {
if (!base::PathExists(updater_executable_path)) {
LOG(ERROR) << "Path to the updater app does not exist!";
return;
return -2;
}
base::CommandLine command(updater_executable_path);
command.AppendSwitch(kInstallCommand);
command.AppendSwitch(kRegisterSwitch);
command.AppendSwitchASCII(kAppIdSwitch, TEST_APP_FULLNAME_STRING);
command.AppendSwitchASCII(kAppVersionSwitch, TEST_APP_VERSION_STRING);
command.AppendSwitchASCII("--vmodule", "*/updater/*=2");
std::string output;
int exit_code = 0;
......@@ -101,11 +74,10 @@ void InstallUpdater() {
if (exit_code != 0) {
LOG(ERROR) << "Couldn't install the updater. Exit code: " << exit_code;
return;
return exit_code;
}
// Now that the updater is installed successfully, we should swap.
SwapUpdater(updater_bundle_path);
return 0;
}
} // namespace updater
......@@ -8,9 +8,10 @@
namespace updater {
void InstallUpdater() {
int InstallUpdater() {
// TODO(1068693): Implement TestApp Functionality.
NOTIMPLEMENTED();
return 0;
}
} // namespace updater
......@@ -19,22 +19,9 @@
#include "base/version.h"
#import "chrome/updater/app/server/mac/service_protocol.h"
#import "chrome/updater/app/server/mac/update_service_wrappers.h"
#import "chrome/updater/mac/xpc_service_names.h"
#include "chrome/updater/test/test_app/test_app_version.h"
namespace {
NSString* GetLaunchdServiceName() {
return base::SysUTF8ToNSString(
base::StrCat({UPDATER_APP_BUNDLE_IDENTIFIER_STRING, ".service"}));
}
NSString* GetMachServiceName() {
return [GetLaunchdServiceName()
stringByAppendingFormat:@".%lu", [GetLaunchdServiceName() hash]];
}
} // namespace
@interface CRUUpdateClientOnDemandImpl : NSObject <CRUUpdateChecking> {
base::scoped_nsobject<NSXPCConnection> _xpcConnection;
}
......@@ -48,7 +35,7 @@ NSString* GetMachServiceName() {
- (instancetype)init {
if (self = [super init]) {
_xpcConnection.reset([[NSXPCConnection alloc]
initWithMachServiceName:GetMachServiceName()
initWithMachServiceName:updater::GetServiceMachName()
options:0]);
_xpcConnection.get().remoteObjectInterface =
......
......@@ -13,7 +13,9 @@
#include "build/build_config.h"
#include "chrome/updater/app/app.h"
#include "chrome/updater/app/app_install.h"
#include "chrome/updater/app/app_register.h"
#include "chrome/updater/app/app_uninstall.h"
#include "chrome/updater/app/app_update.h"
#include "chrome/updater/app/app_wake.h"
#include "chrome/updater/configurator.h"
#include "chrome/updater/constants.h"
......@@ -99,18 +101,20 @@ int HandleUpdaterCommands(const base::CommandLine* command_line) {
#endif
}
#if defined(OS_MAC)
if (command_line->HasSwitch(kUpdateSwitch))
return MakeAppInstall()->Run();
#endif // OS_MAC
return MakeAppUpdate()->Run();
if (command_line->HasSwitch(kRegisterSwitch) &&
command_line->HasSwitch(kAppIdSwitch))
return MakeAppRegister()->Run();
#if defined(OS_WIN)
if (command_line->HasSwitch(kComServiceSwitch))
return ServiceMain::RunComService(command_line);
#endif // OS_WIN
if (command_line->HasSwitch(kInstallSwitch))
return MakeAppInstall()->Run();
#endif // OS_WIN
if (command_line->HasSwitch(kUninstallSwitch))
return MakeAppUninstall()->Run();
......
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