Don't show supervised user as "already on this device" while they're being imported.
[chromium-blink-merge.git] / chrome / browser / ui / webui / help / version_updater_win.cc
blobb62c7afed5bf1c694509b0dbbbf7b9ff55c952c1
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 "base/memory/weak_ptr.h"
6 #include "base/strings/string16.h"
7 #include "base/task_runner_util.h"
8 #include "base/win/win_util.h"
9 #include "base/win/windows_version.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/first_run/upgrade_util.h"
12 #include "chrome/browser/google/google_update_win.h"
13 #include "chrome/browser/lifetime/application_lifetime.h"
14 #include "chrome/browser/ui/webui/help/version_updater.h"
15 #include "chrome/grit/generated_resources.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/web_contents.h"
18 #include "ui/aura/window.h"
19 #include "ui/aura/window_tree_host.h"
20 #include "ui/base/l10n/l10n_util.h"
21 #include "ui/gfx/native_widget_types.h"
23 namespace {
25 // Windows implementation of version update functionality, used by the WebUI
26 // About/Help page.
27 class VersionUpdaterWin : public VersionUpdater, public UpdateCheckDelegate {
28 public:
29 // |owner_widget| is the parent widget hosting the update check UI. Any UI
30 // needed to install an update (e.g., a UAC prompt for a system-level install)
31 // will be parented to this widget.
32 explicit VersionUpdaterWin(gfx::AcceleratedWidget owner_widget);
33 ~VersionUpdaterWin() override;
35 // VersionUpdater:
36 void CheckForUpdate(const StatusCallback& callback) override;
37 void RelaunchBrowser() const override;
39 // UpdateCheckDelegate:
40 void OnUpdateCheckComplete(const base::string16& new_version) override;
41 void OnUpgradeProgress(int progress,
42 const base::string16& new_version) override;
43 void OnUpgradeComplete(const base::string16& new_version) override;
44 void OnError(GoogleUpdateErrorCode error_code,
45 const base::string16& error_message,
46 const base::string16& new_version) override;
48 private:
49 void BeginUpdateCheckOnFileThread(bool install_update_if_possible);
51 // A task run on the UI thread with the result of checking for a pending
52 // restart.
53 void OnPendingRestartCheck(bool is_update_pending_restart);
55 // The widget owning the UI for the update check.
56 gfx::AcceleratedWidget owner_widget_;
58 // Callback used to communicate update status to the client.
59 StatusCallback callback_;
61 // Used for callbacks.
62 base::WeakPtrFactory<VersionUpdaterWin> weak_factory_;
64 DISALLOW_COPY_AND_ASSIGN(VersionUpdaterWin);
67 VersionUpdaterWin::VersionUpdaterWin(gfx::AcceleratedWidget owner_widget)
68 : owner_widget_(owner_widget), weak_factory_(this) {
71 VersionUpdaterWin::~VersionUpdaterWin() {
74 void VersionUpdaterWin::CheckForUpdate(const StatusCallback& callback) {
75 // There is no supported integration with Google Update for Chromium.
76 callback_ = callback;
78 // On-demand updates for Chrome don't work in Vista RTM when UAC is turned
79 // off. So, in this case, the version updater must not mention
80 // on-demand updates. Silent updates (in the background) should still
81 // work as before - enabling UAC or installing the latest service pack
82 // for Vista is another option.
83 if (!(base::win::GetVersion() == base::win::VERSION_VISTA &&
84 (base::win::OSInfo::GetInstance()->service_pack().major == 0) &&
85 !base::win::UserAccountControlIsEnabled())) {
86 callback_.Run(CHECKING, 0, base::string16());
87 BeginUpdateCheckOnFileThread(false /* !install_update_if_possible */);
91 void VersionUpdaterWin::RelaunchBrowser() const {
92 chrome::AttemptRestart();
95 void VersionUpdaterWin::OnUpdateCheckComplete(
96 const base::string16& new_version) {
97 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
98 Status status = CHECKING;
99 if (new_version.empty()) {
100 // Google Update says that no new version is available. Check to see if a
101 // restart is needed for a previously-applied update to take effect.
102 if (base::PostTaskAndReplyWithResult(
103 content::BrowserThread::GetBlockingPool(),
104 FROM_HERE,
105 base::Bind(&upgrade_util::IsUpdatePendingRestart),
106 base::Bind(&VersionUpdaterWin::OnPendingRestartCheck,
107 weak_factory_.GetWeakPtr()))) {
108 // Early exit since callback_ will be Run in OnPendingRestartCheck.
109 return;
111 // Failure to post the task means that Chrome is shutting down. A pending
112 // update (if there is one) will be applied as Chrome exits, so tell the
113 // caller that it is up to date in either case.
114 status = UPDATED;
115 } else {
116 // Notify the caller that the update is now beginning and initiate it.
117 status = UPDATING;
118 BeginUpdateCheckOnFileThread(true /* install_update_if_possible */);
120 callback_.Run(status, 0, base::string16());
123 void VersionUpdaterWin::OnUpgradeProgress(int progress,
124 const base::string16& new_version) {
125 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
126 callback_.Run(UPDATING, progress, base::string16());
129 void VersionUpdaterWin::OnUpgradeComplete(const base::string16& new_version) {
130 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
131 callback_.Run(NEARLY_UPDATED, 0, base::string16());
134 void VersionUpdaterWin::OnError(GoogleUpdateErrorCode error_code,
135 const base::string16& error_message,
136 const base::string16& new_version) {
137 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
138 base::string16 message;
140 // Current versions of Google Update provide a nice message for the policy
141 // case. Use this generic error for the policy case only if no message from
142 // Google Update is present.
143 if (error_code != GOOGLE_UPDATE_DISABLED_BY_POLICY || error_message.empty())
144 message = l10n_util::GetStringFUTF16Int(IDS_UPGRADE_ERROR, error_code);
146 if (!error_message.empty()) {
147 message += l10n_util::GetStringFUTF16(
148 IDS_ABOUT_BOX_ERROR_DURING_UPDATE_CHECK, error_message);
150 callback_.Run(FAILED, 0, message);
153 void VersionUpdaterWin::BeginUpdateCheckOnFileThread(
154 bool install_update_if_possible) {
155 BeginUpdateCheck(content::BrowserThread::GetMessageLoopProxyForThread(
156 content::BrowserThread::FILE),
157 g_browser_process->GetApplicationLocale(),
158 install_update_if_possible, owner_widget_,
159 weak_factory_.GetWeakPtr());
162 void VersionUpdaterWin::OnPendingRestartCheck(bool is_update_pending_restart) {
163 callback_.Run(is_update_pending_restart ? NEARLY_UPDATED : UPDATED, 0,
164 base::string16());
167 } // namespace
169 VersionUpdater* VersionUpdater::Create(content::WebContents* web_contents) {
170 // Retrieve the HWND for the browser window that is hosting the update check.
171 // This will be used as the parent for a UAC prompt, if needed. It's possible
172 // this this window will no longer have focus by the time UAC is needed. In
173 // that case, the UAC prompt will appear in the taskbar and will require a
174 // user click. This is the least surprising thing we can do for the user, and
175 // is the intended behavior for Windows applications. It's also possible that
176 // the browser window hosting the update check will have been closed by the
177 // time the UAC prompt is needed. This will behave similarly.
178 return new VersionUpdaterWin(web_contents->GetTopLevelNativeWindow()
179 ->GetHost()
180 ->GetAcceleratedWidget());