Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / webui / help / version_updater_chromeos.cc
blob1146ec3962b0902af5e82fd295f75150bb2a9a1c
1 // Copyright (c) 2012 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.
5 #include "chrome/browser/ui/webui/help/version_updater_chromeos.h"
7 #include <cmath>
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/chromeos/login/startup_utils.h"
13 #include "chrome/browser/chromeos/login/wizard_controller.h"
14 #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h"
15 #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h"
16 #include "chrome/browser/chromeos/settings/cros_settings.h"
17 #include "chrome/browser/ui/webui/help/help_utils_chromeos.h"
18 #include "chrome/grit/generated_resources.h"
19 #include "chromeos/dbus/dbus_thread_manager.h"
20 #include "chromeos/dbus/power_manager_client.h"
21 #include "chromeos/network/network_handler.h"
22 #include "chromeos/network/network_state.h"
23 #include "chromeos/network/network_state_handler.h"
24 #include "chromeos/settings/cros_settings_names.h"
25 #include "content/public/browser/web_contents.h"
26 #include "third_party/cros_system_api/dbus/service_constants.h"
27 #include "ui/base/l10n/l10n_util.h"
29 using chromeos::CrosSettings;
30 using chromeos::DBusThreadManager;
31 using chromeos::OwnerSettingsServiceChromeOS;
32 using chromeos::OwnerSettingsServiceChromeOSFactory;
33 using chromeos::UpdateEngineClient;
34 using chromeos::WizardController;
36 namespace {
38 // Network status in the context of device update.
39 enum NetworkStatus {
40 // It's allowed in device policy to use current network for update.
41 NETWORK_STATUS_ALLOWED = 0,
42 // It's disallowed in device policy to use current network for update.
43 NETWORK_STATUS_DISALLOWED,
44 // Device is in offline state.
45 NETWORK_STATUS_OFFLINE
48 const bool kDefaultAutoUpdateDisabled = false;
50 NetworkStatus GetNetworkStatus(const chromeos::NetworkState* network) {
51 if (!network || !network->IsConnectedState()) // Offline state.
52 return NETWORK_STATUS_OFFLINE;
54 // The connection type checking strategy must be the same as the one
55 // used in update engine.
56 if (network->type() == shill::kTypeBluetooth)
57 return NETWORK_STATUS_DISALLOWED;
58 if (network->type() == shill::kTypeCellular &&
59 !help_utils_chromeos::IsUpdateOverCellularAllowed()) {
60 return NETWORK_STATUS_DISALLOWED;
62 return NETWORK_STATUS_ALLOWED;
65 // Returns true if auto-update is disabled by the system administrator.
66 bool IsAutoUpdateDisabled() {
67 bool update_disabled = kDefaultAutoUpdateDisabled;
68 chromeos::CrosSettings* settings = chromeos::CrosSettings::Get();
69 if (!settings)
70 return update_disabled;
71 const base::Value* update_disabled_value =
72 settings->GetPref(chromeos::kUpdateDisabled);
73 if (update_disabled_value)
74 CHECK(update_disabled_value->GetAsBoolean(&update_disabled));
75 return update_disabled;
78 // Returns whether an update is allowed. If not, it calls the callback with
79 // the appropriate status.
80 bool EnsureCanUpdate(const VersionUpdater::StatusCallback& callback) {
81 if (IsAutoUpdateDisabled()) {
82 callback.Run(VersionUpdater::FAILED, 0,
83 l10n_util::GetStringUTF16(IDS_UPGRADE_DISABLED_BY_POLICY));
84 return false;
87 chromeos::NetworkStateHandler* network_state_handler =
88 chromeos::NetworkHandler::Get()->network_state_handler();
89 const chromeos::NetworkState* network =
90 network_state_handler->DefaultNetwork();
92 // Don't allow an update if we're currently offline or connected
93 // to a network for which updates are disallowed.
94 NetworkStatus status = GetNetworkStatus(network);
95 if (status == NETWORK_STATUS_OFFLINE) {
96 callback.Run(VersionUpdater::FAILED_OFFLINE, 0,
97 l10n_util::GetStringUTF16(IDS_UPGRADE_OFFLINE));
98 return false;
99 } else if (status == NETWORK_STATUS_DISALLOWED) {
100 base::string16 message =
101 l10n_util::GetStringFUTF16(
102 IDS_UPGRADE_DISALLOWED,
103 help_utils_chromeos::GetConnectionTypeAsUTF16(network->type()));
104 callback.Run(VersionUpdater::FAILED_CONNECTION_TYPE_DISALLOWED, 0, message);
105 return false;
108 return true;
111 } // namespace
113 VersionUpdater* VersionUpdater::Create(content::WebContents* web_contents) {
114 return new VersionUpdaterCros(web_contents);
117 void VersionUpdaterCros::GetUpdateStatus(const StatusCallback& callback) {
118 callback_ = callback;
120 if (!EnsureCanUpdate(callback))
121 return;
123 UpdateEngineClient* update_engine_client =
124 DBusThreadManager::Get()->GetUpdateEngineClient();
125 if (!update_engine_client->HasObserver(this))
126 update_engine_client->AddObserver(this);
128 this->UpdateStatusChanged(
129 DBusThreadManager::Get()->GetUpdateEngineClient()->GetLastStatus());
132 void VersionUpdaterCros::CheckForUpdate(const StatusCallback& callback) {
133 callback_ = callback;
135 if (!EnsureCanUpdate(callback))
136 return;
138 UpdateEngineClient* update_engine_client =
139 DBusThreadManager::Get()->GetUpdateEngineClient();
140 if (!update_engine_client->HasObserver(this))
141 update_engine_client->AddObserver(this);
143 if (update_engine_client->GetLastStatus().status !=
144 UpdateEngineClient::UPDATE_STATUS_IDLE) {
145 check_for_update_when_idle_ = true;
146 return;
148 check_for_update_when_idle_ = false;
150 // Make sure that libcros is loaded and OOBE is complete.
151 if (!WizardController::default_controller() ||
152 chromeos::StartupUtils::IsDeviceRegistered()) {
153 update_engine_client->RequestUpdateCheck(base::Bind(
154 &VersionUpdaterCros::OnUpdateCheck, weak_ptr_factory_.GetWeakPtr()));
158 void VersionUpdaterCros::RelaunchBrowser() const {
159 DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
162 void VersionUpdaterCros::SetChannel(const std::string& channel,
163 bool is_powerwash_allowed) {
164 OwnerSettingsServiceChromeOS* service =
165 context_
166 ? OwnerSettingsServiceChromeOSFactory::GetInstance()
167 ->GetForBrowserContext(context_)
168 : nullptr;
169 // For local owner set the field in the policy blob.
170 if (service)
171 service->SetString(chromeos::kReleaseChannel, channel);
172 DBusThreadManager::Get()->GetUpdateEngineClient()->
173 SetChannel(channel, is_powerwash_allowed);
176 void VersionUpdaterCros::GetChannel(bool get_current_channel,
177 const ChannelCallback& cb) {
178 UpdateEngineClient* update_engine_client =
179 DBusThreadManager::Get()->GetUpdateEngineClient();
181 // Request the channel information.
182 update_engine_client->GetChannel(get_current_channel, cb);
185 VersionUpdaterCros::VersionUpdaterCros(content::WebContents* web_contents)
186 : context_(web_contents ? web_contents->GetBrowserContext() : nullptr),
187 last_operation_(UpdateEngineClient::UPDATE_STATUS_IDLE),
188 check_for_update_when_idle_(false),
189 weak_ptr_factory_(this) {
192 VersionUpdaterCros::~VersionUpdaterCros() {
193 UpdateEngineClient* update_engine_client =
194 DBusThreadManager::Get()->GetUpdateEngineClient();
195 update_engine_client->RemoveObserver(this);
198 void VersionUpdaterCros::UpdateStatusChanged(
199 const UpdateEngineClient::Status& status) {
200 Status my_status = UPDATED;
201 int progress = 0;
202 base::string16 message;
204 // If the updater is currently idle, just show the last operation (unless it
205 // was previously checking for an update -- in that case, the system is
206 // up-to-date now). See http://crbug.com/120063 for details.
207 UpdateEngineClient::UpdateStatusOperation operation_to_show = status.status;
208 if (status.status == UpdateEngineClient::UPDATE_STATUS_IDLE &&
209 last_operation_ !=
210 UpdateEngineClient::UPDATE_STATUS_CHECKING_FOR_UPDATE) {
211 operation_to_show = last_operation_;
214 switch (operation_to_show) {
215 case UpdateEngineClient::UPDATE_STATUS_ERROR:
216 case UpdateEngineClient::UPDATE_STATUS_REPORTING_ERROR_EVENT:
217 case UpdateEngineClient::UPDATE_STATUS_ATTEMPTING_ROLLBACK:
218 // This path previously used the FAILED status and IDS_UPGRADE_ERROR, but
219 // the update engine reports errors for some conditions that shouldn't
220 // actually be displayed as errors to users: http://crbug.com/146919.
221 // Just use the UPDATED status instead.
222 break;
223 case UpdateEngineClient::UPDATE_STATUS_CHECKING_FOR_UPDATE:
224 my_status = CHECKING;
225 break;
226 case UpdateEngineClient::UPDATE_STATUS_DOWNLOADING:
227 progress = static_cast<int>(round(status.download_progress * 100));
228 // Fall through.
229 case UpdateEngineClient::UPDATE_STATUS_UPDATE_AVAILABLE:
230 my_status = UPDATING;
231 break;
232 case UpdateEngineClient::UPDATE_STATUS_VERIFYING:
233 case UpdateEngineClient::UPDATE_STATUS_FINALIZING:
234 // Once the download is finished, keep the progress at 100; it shouldn't
235 // go down while the status is the same.
236 progress = 100;
237 my_status = UPDATING;
238 break;
239 case UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT:
240 my_status = NEARLY_UPDATED;
241 break;
242 default:
243 break;
246 callback_.Run(my_status, progress, message);
247 last_operation_ = status.status;
249 if (check_for_update_when_idle_ &&
250 status.status == UpdateEngineClient::UPDATE_STATUS_IDLE) {
251 CheckForUpdate(callback_);
255 void VersionUpdaterCros::OnUpdateCheck(
256 UpdateEngineClient::UpdateCheckResult result) {
257 // If version updating is not implemented, this binary is the most up-to-date
258 // possible with respect to automatic updating.
259 if (result == UpdateEngineClient::UPDATE_RESULT_NOTIMPLEMENTED)
260 callback_.Run(UPDATED, 0, base::string16());