1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/updater/app/app_server.h"
6
7 #include <memory>
8
9 #include "base/bind.h"
10 #include "base/logging.h"
11 #include "base/memory/scoped_refptr.h"
12 #include "base/version.h"
13 #include "chrome/updater/configurator.h"
14 #include "chrome/updater/constants.h"
15 #include "chrome/updater/control_service.h"
16 #include "chrome/updater/control_service_impl.h"
17 #include "chrome/updater/control_service_impl_inactive.h"
18 #include "chrome/updater/persisted_data.h"
19 #include "chrome/updater/prefs.h"
20 #include "chrome/updater/update_service.h"
21 #include "chrome/updater/update_service_impl.h"
22 #include "chrome/updater/update_service_impl_inactive.h"
23 #include "chrome/updater/updater_version.h"
24 #include "components/prefs/pref_service.h"
25
26 namespace updater {
27
28 AppServer::AppServer() = default;
29
30 AppServer::~AppServer() = default;
31
Initialize()32 void AppServer::Initialize() {
33 first_task_ = ModeCheck();
34 }
35
ModeCheck()36 base::OnceClosure AppServer::ModeCheck() {
37 std::unique_ptr<GlobalPrefs> global_prefs = CreateGlobalPrefs();
38 if (!global_prefs) {
39 return base::BindOnce(&AppServer::Shutdown, this,
40 kErrorFailedToLockPrefsMutex);
41 }
42
43 const base::Version this_version(UPDATER_VERSION_STRING);
44 const base::Version active_version(global_prefs->GetActiveVersion());
45
46 VLOG(2) << "This version: " << this_version.GetString()
47 << ", active version: " << active_version.GetString();
48
49 if (this_version < active_version) {
50 global_prefs = nullptr;
51 uninstall_ = true;
52 return base::BindOnce(&AppServer::ActiveDuty, this,
53 MakeInactiveUpdateService(),
54 MakeInactiveControlService());
55 }
56
57 if (active_version != base::Version("0") && active_version != this_version) {
58 std::unique_ptr<LocalPrefs> local_prefs = CreateLocalPrefs();
59 if (!local_prefs->GetQualified()) {
60 global_prefs = nullptr;
61 return base::BindOnce(&AppServer::Qualify, this, std::move(local_prefs));
62 }
63 }
64
65 if (this_version > active_version || global_prefs->GetSwapping()) {
66 if (!SwapVersions(global_prefs.get()))
67 return base::BindOnce(&AppServer::Shutdown, this, kErrorFailedToSwap);
68 }
69
70 config_ = base::MakeRefCounted<Configurator>(std::move(global_prefs));
71 return base::BindOnce(&AppServer::ActiveDuty, this,
72 base::MakeRefCounted<UpdateServiceImpl>(config_),
73 base::MakeRefCounted<ControlServiceImpl>(config_));
74 }
75
Uninitialize()76 void AppServer::Uninitialize() {
77 if (config_)
78 PrefsCommitPendingWrites(config_->GetPrefService());
79 if (uninstall_) {
80 VLOG(1) << "Uninstalling version " << UPDATER_VERSION_STRING;
81 UninstallSelf();
82 }
83 }
84
FirstTaskRun()85 void AppServer::FirstTaskRun() {
86 std::move(first_task_).Run();
87 }
88
Qualify(std::unique_ptr<LocalPrefs> local_prefs)89 void AppServer::Qualify(std::unique_ptr<LocalPrefs> local_prefs) {
90 // For now, assume qualification succeeds.
91 DVLOG(2) << __func__;
92 local_prefs->SetQualified(true);
93 PrefsCommitPendingWrites(local_prefs->GetPrefService());
94
95 // Start ActiveDuty with inactive service implementations. To use active
96 // implementations, the server would have to ModeCheck again.
97 ActiveDuty(MakeInactiveUpdateService(), MakeInactiveControlService());
98 }
99
SwapVersions(GlobalPrefs * global_prefs)100 bool AppServer::SwapVersions(GlobalPrefs* global_prefs) {
101 global_prefs->SetSwapping(true);
102 PrefsCommitPendingWrites(global_prefs->GetPrefService());
103 bool result = SwapRPCInterfaces();
104 if (!result)
105 return false;
106 global_prefs->SetActiveVersion(UPDATER_VERSION_STRING);
107 scoped_refptr<PersistedData> persisted_data =
108 base::MakeRefCounted<PersistedData>(global_prefs->GetPrefService());
109 if (!persisted_data->GetProductVersion(kUpdaterAppId).IsValid()) {
110 persisted_data->SetProductVersion(kUpdaterAppId,
111 base::Version(UPDATER_VERSION_STRING));
112 }
113 global_prefs->SetSwapping(false);
114 PrefsCommitPendingWrites(global_prefs->GetPrefService());
115 return true;
116 }
117
118 } // namespace updater
119