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