172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/about_chrome_view.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#if defined(OS_WIN)
821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <commdlg.h>
921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#endif  // defined(OS_WIN)
1021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <algorithm>
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string>
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector>
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/callback.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/i18n/rtl.h"
173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h"
19731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/win/windows_version.h"
203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "chrome/browser/google/google_util.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/metrics/user_metrics.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/platform_util.h"
233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/prefs/pref_service.h"
24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_list.h"
2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/window.h"
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_constants.h"
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_version_info.h"
283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/pref_names.h"
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h"
3021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/installer/util/browser_distribution.h"
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/chromium_strings.h"
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h"
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/locale_settings.h"
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/theme_resources.h"
3572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h"
3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/resource/resource_bundle.h"
3772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/canvas.h"
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/controls/textfield/textfield.h"
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/controls/throbber.h"
4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "views/layout/layout_constants.h"
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/view_text_utils.h"
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/widget/widget.h"
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/window/window.h"
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/webkit_glue.h"
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
473f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/win/win_util.h"
4872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/restart_message_box.h"
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/installer/util/install_util.h"
5021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#endif  // defined(OS_WIN)
5121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
5221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#if defined(OS_WIN) || defined(OS_CHROMEOS)
5321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/browser_process.h"
5421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#endif  // defined(OS_WIN) || defined(OS_CHROMEOS)
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The pixel width of the version text field. Ideally, we'd like to have the
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// bounds set to the edge of the icon. However, the icon is not a view but a
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// part of the background, so we have to hard code the width to make sure
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the version field doesn't overlap it.
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kVersionFieldWidth = 195;
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// These are used as placeholder text around the links in the text in the about
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// dialog.
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst wchar_t* kBeginLink = L"BEGIN_LINK";
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst wchar_t* kEndLink = L"END_LINK";
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst wchar_t* kBeginLinkChr = L"BEGIN_LINK_CHR";
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst wchar_t* kBeginLinkOss = L"BEGIN_LINK_OSS";
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst wchar_t* kEndLinkChr = L"END_LINK_CHR";
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst wchar_t* kEndLinkOss = L"END_LINK_OSS";
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The background bitmap used to draw the background color for the About box
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// and the separator line (this is the image we will draw the logo on top of).
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const SkBitmap* kBackgroundBmp = NULL;
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns a substring from |text| between start and end.
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::wstring StringSubRange(const std::wstring& text, size_t start,
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            size_t end) {
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(end > start);
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return text.substr(start, end - start);
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace browser {
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Declared in browser_dialogs.h so that others don't
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // need to depend on our .h.
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  views::Window* ShowAboutChromeView(gfx::NativeWindow parent,
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     Profile* profile) {
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      views::Window* about_chrome_window =
92731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        browser::CreateViewsWindow(parent,
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        gfx::Rect(),
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        new AboutChromeView(profile));
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      about_chrome_window->Show();
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return about_chrome_window;
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace browser
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// AboutChromeView, public:
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochAboutChromeView::AboutChromeView(Profile* profile)
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : profile_(profile),
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      about_dlg_background_logo_(NULL),
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      about_title_label_(NULL),
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      version_label_(NULL),
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      os_version_label_(NULL),
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      copyright_label_(NULL),
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      main_text_label_(NULL),
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      main_text_label_height_(0),
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      chromium_url_(NULL),
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      open_source_url_(NULL),
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      terms_of_service_url_(NULL),
1183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      restart_button_visible_(false),
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      chromium_url_appears_first_(true),
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      text_direction_is_rtl_(false) {
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(profile);
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loader_.GetVersion(&consumer_,
124201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                     NewCallback(this, &AboutChromeView::OnOSVersion),
125201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                     chromeos::VersionLoader::VERSION_FULL);
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Init();
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN) || defined(OS_CHROMEOS)
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  google_updater_ = new GoogleUpdate();
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  google_updater_->set_status_listener(this);
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (kBackgroundBmp == NULL) {
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ResourceBundle& rb = ResourceBundle::GetSharedInstance();
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    kBackgroundBmp = rb.GetBitmapNamed(IDR_ABOUT_BACKGROUND_COLOR);
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochAboutChromeView::~AboutChromeView() {
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN) || defined(OS_CHROMEOS)
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The Google Updater will hold a pointer to us until it reports status, so we
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // need to let it know that we will no longer be listening.
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (google_updater_)
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    google_updater_->set_status_listener(NULL);
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AboutChromeView::Init() {
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  text_direction_is_rtl_ = base::i18n::IsRTL();
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  chrome::VersionInfo version_info;
1543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!version_info.is_valid()) {
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED() << L"Failed to initialize about window";
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
15921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  current_version_ = version_info.Version();
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
16172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // This code only runs as a result of the user opening the About box so
16272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // doing registry access to get the version string modifier should be fine.
16372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::ThreadRestrictions::ScopedAllowIO allow_io;
1643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string version_modifier = platform_util::GetVersionStringModifier();
1653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!version_modifier.empty())
16621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    version_details_ += " " + version_modifier;
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(GOOGLE_CHROME_BUILD)
16921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  version_details_ += " (";
17021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  version_details_ += version_info.LastChange();
17121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  version_details_ += ")";
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Views we will add to the *parent* of this dialog, since it will display
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // next to the buttons which we don't draw ourselves.
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  throbber_.reset(new views::Throbber(50, true));
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  throbber_->set_parent_owned(false);
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  throbber_->SetVisible(false);
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SkBitmap* success_image = rb.GetBitmapNamed(IDR_UPDATE_UPTODATE);
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  success_indicator_.SetImage(*success_image);
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  success_indicator_.set_parent_owned(false);
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SkBitmap* update_available_image = rb.GetBitmapNamed(IDR_UPDATE_AVAILABLE);
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  update_available_indicator_.SetImage(*update_available_image);
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  update_available_indicator_.set_parent_owned(false);
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SkBitmap* timeout_image = rb.GetBitmapNamed(IDR_UPDATE_FAIL);
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  timeout_indicator_.SetImage(*timeout_image);
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  timeout_indicator_.set_parent_owned(false);
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  update_label_.SetVisible(false);
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  update_label_.set_parent_owned(false);
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Regular view controls we draw by ourself. First, we add the background
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // image for the dialog. We have two different background bitmaps, one for
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // LTR UIs and one for RTL UIs. We load the correct bitmap based on the UI
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // layout of the view.
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  about_dlg_background_logo_ = new views::ImageView();
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SkBitmap* about_background_logo = rb.GetBitmapNamed(base::i18n::IsRTL() ?
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      IDR_ABOUT_BACKGROUND_RTL : IDR_ABOUT_BACKGROUND);
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  about_dlg_background_logo_->SetImage(*about_background_logo);
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddChildView(about_dlg_background_logo_);
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add the dialog labels.
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  about_title_label_ = new views::Label(
2083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      UTF16ToWide(l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)));
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  about_title_label_->SetFont(ResourceBundle::GetSharedInstance().GetFont(
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ResourceBundle::BaseFont).DeriveFont(18));
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  about_title_label_->SetColor(SK_ColorBLACK);
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddChildView(about_title_label_);
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This is a text field so people can copy the version number from the dialog.
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  version_label_ = new views::Textfield();
21621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  version_label_->SetText(ASCIIToUTF16(current_version_ + version_details_));
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  version_label_->SetReadOnly(true);
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  version_label_->RemoveBorder();
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  version_label_->SetTextColor(SK_ColorBLACK);
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  version_label_->SetBackgroundColor(SK_ColorWHITE);
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  version_label_->SetFont(ResourceBundle::GetSharedInstance().GetFont(
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ResourceBundle::BaseFont));
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddChildView(version_label_);
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  os_version_label_ = new views::Textfield(views::Textfield::STYLE_MULTILINE);
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  os_version_label_->SetReadOnly(true);
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  os_version_label_->RemoveBorder();
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  os_version_label_->SetTextColor(SK_ColorBLACK);
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  os_version_label_->SetBackgroundColor(SK_ColorWHITE);
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  os_version_label_->SetFont(ResourceBundle::GetSharedInstance().GetFont(
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ResourceBundle::BaseFont));
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddChildView(os_version_label_);
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The copyright URL portion of the main label.
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  copyright_label_ = new views::Label(
2383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      UTF16ToWide(l10n_util::GetStringUTF16(IDS_ABOUT_VERSION_COPYRIGHT)));
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  copyright_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddChildView(copyright_label_);
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  main_text_label_ = new views::Label(L"");
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Figure out what to write in the main label of the About box.
2453f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  std::wstring text =
2463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      UTF16ToWide(l10n_util::GetStringUTF16(IDS_ABOUT_VERSION_LICENSE));
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  chromium_url_appears_first_ =
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      text.find(kBeginLinkChr) < text.find(kBeginLinkOss);
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  size_t link1 = text.find(kBeginLink);
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(link1 != std::wstring::npos);
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  size_t link1_end = text.find(kEndLink, link1);
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(link1_end != std::wstring::npos);
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  size_t link2 = text.find(kBeginLink, link1_end);
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(link2 != std::wstring::npos);
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  size_t link2_end = text.find(kEndLink, link2);
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(link1_end != std::wstring::npos);
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  main_label_chunk1_ = text.substr(0, link1);
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  main_label_chunk2_ = StringSubRange(text, link1_end + wcslen(kEndLinkOss),
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                      link2);
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  main_label_chunk3_ = text.substr(link2_end + wcslen(kEndLinkOss));
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The Chromium link within the main text of the dialog.
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  chromium_url_ = new views::Link(
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      StringSubRange(text, text.find(kBeginLinkChr) + wcslen(kBeginLinkChr),
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                     text.find(kEndLinkChr)));
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddChildView(chromium_url_);
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  chromium_url_->SetController(this);
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The Open Source link within the main text of the dialog.
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  open_source_url_ = new views::Link(
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      StringSubRange(text, text.find(kBeginLinkOss) + wcslen(kBeginLinkOss),
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                     text.find(kEndLinkOss)));
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddChildView(open_source_url_);
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  open_source_url_->SetController(this);
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add together all the strings in the dialog for the purpose of calculating
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the height of the dialog. The space for the Terms of Service string is not
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // included (it is added later, if needed).
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::wstring full_text = main_label_chunk1_ + chromium_url_->GetText() +
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           main_label_chunk2_ + open_source_url_->GetText() +
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           main_label_chunk3_;
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dialog_dimensions_ = views::Window::GetLocalizedContentsSize(
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      IDS_ABOUT_DIALOG_WIDTH_CHARS,
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      IDS_ABOUT_DIALOG_MINIMUM_HEIGHT_LINES);
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Create a label and add the full text so we can query it for the height.
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  views::Label dummy_text(full_text);
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dummy_text.SetMultiLine(true);
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Font font =
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont);
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add up the height of the various elements on the page.
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int height = about_background_logo->height() +
298dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      views::kRelatedControlVerticalSpacing +
299dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      // Copyright line.
300dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      font.GetHeight() +
301dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      // Main label.
302dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      dummy_text.GetHeightForWidth(
303dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          dialog_dimensions_.width() - (2 * views::kPanelHorizMargin)) +
304dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          views::kRelatedControlVerticalSpacing;
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(GOOGLE_CHROME_BUILD)
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<size_t> url_offsets;
3083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  text = UTF16ToWide(l10n_util::GetStringFUTF16(IDS_ABOUT_TERMS_OF_SERVICE,
3093f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                                string16(),
3103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                                string16(),
3113f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                                &url_offsets));
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  main_label_chunk4_ = text.substr(0, url_offsets[0]);
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  main_label_chunk5_ = text.substr(url_offsets[0]);
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The Terms of Service URL at the bottom.
3173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  terms_of_service_url_ = new views::Link(
3183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      UTF16ToWide(l10n_util::GetStringUTF16(IDS_TERMS_OF_SERVICE)));
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddChildView(terms_of_service_url_);
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  terms_of_service_url_->SetController(this);
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add the Terms of Service line and some whitespace.
32372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  height += font.GetHeight() + views::kRelatedControlVerticalSpacing;
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Use whichever is greater (the calculated height or the specified minimum
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // height).
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dialog_dimensions_.set_height(std::max(height, dialog_dimensions_.height()));
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// AboutChromeView, views::View implementation:
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Size AboutChromeView::GetPreferredSize() {
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return dialog_dimensions_;
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AboutChromeView::Layout() {
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Size panel_size = GetPreferredSize();
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Background image for the dialog.
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Size sz = about_dlg_background_logo_->GetPreferredSize();
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Used to position main text below.
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int background_image_height = sz.height();
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  about_dlg_background_logo_->SetBounds(panel_size.width() - sz.width(), 0,
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        sz.width(), sz.height());
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // First label goes to the top left corner.
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  sz = about_title_label_->GetPreferredSize();
350dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  about_title_label_->SetBounds(
351dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      views::kPanelHorizMargin, views::kPanelVertMargin,
352dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      sz.width(), sz.height());
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Then we have the version number right below it.
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  sz = version_label_->GetPreferredSize();
356dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  version_label_->SetBounds(views::kPanelHorizMargin,
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            about_title_label_->y() +
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                about_title_label_->height() +
35972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                views::kRelatedControlVerticalSpacing,
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            kVersionFieldWidth,
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            sz.height());
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Then we have the version number right below it.
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  sz = os_version_label_->GetPreferredSize();
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  os_version_label_->SetBounds(
367dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      views::kPanelHorizMargin,
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      version_label_->y() +
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          version_label_->height() +
37072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          views::kRelatedControlVerticalSpacing,
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      kVersionFieldWidth,
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      sz.height());
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // For the width of the main text label we want to use up the whole panel
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // width and remaining height, minus a little margin on each side.
37772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  int y_pos = background_image_height + views::kRelatedControlVerticalSpacing;
378dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  sz.set_width(panel_size.width() - 2 * views::kPanelHorizMargin);
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Draw the text right below the background image.
381dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  copyright_label_->SetBounds(views::kPanelHorizMargin,
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              y_pos,
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              sz.width(),
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              sz.height());
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Then the main_text_label.
387dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  main_text_label_->SetBounds(views::kPanelHorizMargin,
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              copyright_label_->y() +
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  copyright_label_->height(),
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              sz.width(),
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              main_text_label_height_);
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Get the y-coordinate of our parent so we can position the text left of the
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // buttons at the bottom.
39572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  gfx::Rect parent_bounds = parent()->GetContentsBounds();
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  sz = throbber_->GetPreferredSize();
398dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  int throbber_topleft_x = views::kPanelHorizMargin;
39972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  int throbber_topleft_y =
40072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      parent_bounds.bottom() - sz.height() - views::kButtonVEdgeMargin - 3;
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  throbber_->SetBounds(throbber_topleft_x, throbber_topleft_y,
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       sz.width(), sz.height());
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This image is hidden (see ViewHierarchyChanged) and displayed on demand.
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  sz = success_indicator_.GetPreferredSize();
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  success_indicator_.SetBounds(throbber_topleft_x, throbber_topleft_y,
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               sz.width(), sz.height());
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This image is hidden (see ViewHierarchyChanged) and displayed on demand.
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  sz = update_available_indicator_.GetPreferredSize();
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  update_available_indicator_.SetBounds(throbber_topleft_x, throbber_topleft_y,
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        sz.width(), sz.height());
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This image is hidden (see ViewHierarchyChanged) and displayed on demand.
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  sz = timeout_indicator_.GetPreferredSize();
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  timeout_indicator_.SetBounds(throbber_topleft_x, throbber_topleft_y,
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               sz.width(), sz.height());
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The update label should be at the bottom of the screen, to the right of
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the throbber. We specify width to the end of the dialog because it contains
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // variable length messages.
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  sz = update_label_.GetPreferredSize();
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int update_label_x = throbber_->x() + throbber_->width() +
42472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                       views::kRelatedControlHorizontalSpacing;
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  update_label_.SetHorizontalAlignment(views::Label::ALIGN_LEFT);
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  update_label_.SetBounds(update_label_x,
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          throbber_topleft_y + 1,
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          parent_bounds.width() - update_label_x,
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          sz.height());
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
433dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid AboutChromeView::OnPaint(gfx::Canvas* canvas) {
434dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  views::View::OnPaint(canvas);
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Draw the background image color (and the separator) across the dialog.
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This will become the background for the logo image at the top of the
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // dialog.
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  canvas->TileImageInt(*kBackgroundBmp, 0, 0,
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       dialog_dimensions_.width(), kBackgroundBmp->height());
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Font font =
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont);
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const gfx::Rect label_bounds = main_text_label_->bounds();
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  views::Link* link1 =
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      chromium_url_appears_first_ ? chromium_url_ : open_source_url_;
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  views::Link* link2 =
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      chromium_url_appears_first_ ? open_source_url_ : chromium_url_;
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Rect* rect1 = chromium_url_appears_first_ ?
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      &chromium_url_rect_ : &open_source_url_rect_;
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Rect* rect2 = chromium_url_appears_first_ ?
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      &open_source_url_rect_ : &chromium_url_rect_;
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This struct keeps track of where to write the next word (which x,y
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // pixel coordinate). This struct is updated after drawing text and checking
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // if we need to wrap.
459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Size position;
460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Draw the first text chunk and position the Chromium url.
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  view_text_utils::DrawTextAndPositionUrl(canvas, main_text_label_,
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      main_label_chunk1_, link1, rect1, &position, text_direction_is_rtl_,
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      label_bounds, font);
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Draw the second text chunk and position the Open Source url.
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  view_text_utils::DrawTextAndPositionUrl(canvas, main_text_label_,
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      main_label_chunk2_, link2, rect2, &position, text_direction_is_rtl_,
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      label_bounds, font);
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Draw the third text chunk (which has no URL associated with it).
469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  view_text_utils::DrawTextAndPositionUrl(canvas, main_text_label_,
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      main_label_chunk3_, NULL, NULL, &position, text_direction_is_rtl_,
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      label_bounds, font);
472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(GOOGLE_CHROME_BUILD)
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Insert a line break and some whitespace.
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  position.set_width(0);
47672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  position.Enlarge(0, font.GetHeight() + views::kRelatedControlVerticalSpacing);
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // And now the Terms of Service and position the TOS url.
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  view_text_utils::DrawTextAndPositionUrl(canvas, main_text_label_,
480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      main_label_chunk4_, terms_of_service_url_, &terms_of_service_url_rect_,
481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      &position, text_direction_is_rtl_, label_bounds, font);
482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The last text chunk doesn't have a URL associated with it.
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  view_text_utils::DrawTextAndPositionUrl(canvas, main_text_label_,
484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       main_label_chunk5_, NULL, NULL, &position, text_direction_is_rtl_,
485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       label_bounds, font);
486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Position the TOS URL within the main label.
488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  terms_of_service_url_->SetBounds(terms_of_service_url_rect_.x(),
489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   terms_of_service_url_rect_.y(),
490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   terms_of_service_url_rect_.width(),
491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   terms_of_service_url_rect_.height());
492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Position the URLs within the main label. First position the Chromium URL
495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // within the main label.
496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  chromium_url_->SetBounds(chromium_url_rect_.x(),
497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           chromium_url_rect_.y(),
498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           chromium_url_rect_.width(),
499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           chromium_url_rect_.height());
500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Then position the Open Source URL within the main label.
501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  open_source_url_->SetBounds(open_source_url_rect_.x(),
502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              open_source_url_rect_.y(),
503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              open_source_url_rect_.width(),
504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              open_source_url_rect_.height());
505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Save the height so we can set the bounds correctly.
5073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  main_text_label_height_ = position.height() + font.GetHeight();
508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AboutChromeView::ViewHierarchyChanged(bool is_add,
511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           views::View* parent,
512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           views::View* child) {
5133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Since we want some of the controls to show up in the same visual row
514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // as the buttons, which are provided by the framework, we must add the
515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // buttons to the non-client view, which is the parent of this view.
516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Similarly, when we're removed from the view hierarchy, we must take care
517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // to remove these items as well.
518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (child == this) {
519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (is_add) {
520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      parent->AddChildView(&update_label_);
521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      parent->AddChildView(throbber_.get());
522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      parent->AddChildView(&success_indicator_);
523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      success_indicator_.SetVisible(false);
524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      parent->AddChildView(&update_available_indicator_);
525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      update_available_indicator_.SetVisible(false);
526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      parent->AddChildView(&timeout_indicator_);
527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      timeout_indicator_.SetVisible(false);
528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // On-demand updates for Chrome don't work in Vista RTM when UAC is turned
531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // off. So, in this case we just want the About box to not mention
532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // on-demand updates. Silent updates (in the background) should still
533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // work as before - enabling UAC or installing the latest service pack
534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // for Vista is another option.
535dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      if (!(base::win::GetVersion() == base::win::VERSION_VISTA &&
536ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            (base::win::OSInfo::GetInstance()->service_pack().major == 0) &&
537dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen            !base::win::UserAccountControlIsEnabled())) {
538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        UpdateStatus(UPGRADE_CHECK_STARTED, GOOGLE_UPDATE_NO_ERROR);
539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // CheckForUpdate(false, ...) means don't upgrade yet.
540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        google_updater_->CheckForUpdate(false, window());
541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_CHROMEOS)
543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      UpdateStatus(UPGRADE_CHECK_STARTED, GOOGLE_UPDATE_NO_ERROR);
544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // CheckForUpdate(false, ...) means don't upgrade yet.
545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      google_updater_->CheckForUpdate(false, window());
546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      parent->RemoveChildView(&update_label_);
549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      parent->RemoveChildView(throbber_.get());
550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      parent->RemoveChildView(&success_indicator_);
551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      parent->RemoveChildView(&update_available_indicator_);
552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      parent->RemoveChildView(&timeout_indicator_);
553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// AboutChromeView, views::DialogDelegate implementation:
559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::wstring AboutChromeView::GetDialogButtonLabel(
561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageBoxFlags::DialogButton button) const {
562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (button == MessageBoxFlags::DIALOGBUTTON_OK) {
56372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return UTF16ToWide(l10n_util::GetStringUTF16(IDS_RELAUNCH_AND_UPDATE));
564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (button == MessageBoxFlags::DIALOGBUTTON_CANCEL) {
5653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (restart_button_visible_)
5663f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      return UTF16ToWide(l10n_util::GetStringUTF16(IDS_NOT_NOW));
567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The OK button (which is the default button) has been re-purposed to be
5683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // 'Restart Now' so we want the Cancel button should have the label
569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // OK but act like a Cancel button in all other ways.
5703f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    return UTF16ToWide(l10n_util::GetStringUTF16(IDS_OK));
571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NOTREACHED();
574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return L"";
575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::wstring AboutChromeView::GetWindowTitle() const {
5783f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return UTF16ToWide(l10n_util::GetStringUTF16(IDS_ABOUT_CHROME_TITLE));
579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool AboutChromeView::IsDialogButtonEnabled(
582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageBoxFlags::DialogButton button) const {
5833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (button == MessageBoxFlags::DIALOGBUTTON_OK && !restart_button_visible_)
584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool AboutChromeView::IsDialogButtonVisible(
590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageBoxFlags::DialogButton button) const {
5913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (button == MessageBoxFlags::DIALOGBUTTON_OK && !restart_button_visible_)
592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// (on ChromeOS) the default focus is ending up in the version field when
598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the update button is hidden. This forces the focus to always be on the
599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// OK button (which is the dialog cancel button, see GetDialogButtonLabel
600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// above).
601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint AboutChromeView::GetDefaultDialogButton() const {
602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return MessageBoxFlags::DIALOGBUTTON_CANCEL;
603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool AboutChromeView::CanResize() const {
606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return false;
607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool AboutChromeView::CanMaximize() const {
610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return false;
611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool AboutChromeView::IsAlwaysOnTop() const {
614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return false;
615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool AboutChromeView::HasAlwaysOnTopMenu() const {
618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return false;
619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool AboutChromeView::IsModal() const {
622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool AboutChromeView::Accept() {
626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN) || defined(OS_CHROMEOS)
6273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Set the flag to restore the last session on shutdown.
6283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  PrefService* pref_service = g_browser_process->local_state();
6293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  pref_service->SetBoolean(prefs::kRestartLastSessionOnShutdown, true);
6303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  BrowserList::CloseAllBrowsersAndExit();
631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
6333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return true;
634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochviews::View* AboutChromeView::GetContentsView() {
637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return this;
638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// AboutChromeView, views::LinkController implementation:
642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AboutChromeView::LinkActivated(views::Link* source,
644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    int event_flags) {
645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url;
6463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (source == terms_of_service_url_) {
647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    url = GURL(chrome::kAboutTermsURL);
6483f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  } else if (source == chromium_url_) {
6493f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    url = google_util::AppendGoogleLocaleParam(
6503f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      GURL(chrome::kChromiumProjectURL));
6513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  } else if (source == open_source_url_) {
652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    url = GURL(chrome::kAboutCreditsURL);
6533f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  } else {
654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED() << "Unknown link source";
6553f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Browser* browser = BrowserList::GetLastActive();
658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->OpenURL(url, GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK);
660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else
661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->OpenURL(url, GURL(), NEW_WINDOW, PageTransition::LINK);
662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AboutChromeView::OnOSVersion(
667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    chromeos::VersionLoader::Handle handle,
668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string version) {
669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This is a hack to "wrap" the very long Test Build version after
671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the version number, the remaining text won't be visible but can
672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // be selected, copied, pasted.
673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string::size_type pos = version.find(" (Test Build");
674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (pos != std::string::npos)
675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    version.replace(pos, 1, "\n");
676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  os_version_label_->SetText(UTF8ToUTF16(version));
678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN) || defined(OS_CHROMEOS)
682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// AboutChromeView, GoogleUpdateStatusListener implementation:
684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AboutChromeView::OnReportResults(GoogleUpdateUpgradeResult result,
686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                      GoogleUpdateErrorCode error_code,
687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                      const std::wstring& version) {
688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Drop the last reference to the object so that it gets cleaned up here.
689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  google_updater_ = NULL;
690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make a note of which version Google Update is reporting is the latest
692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // version.
693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  new_version_available_ = version;
694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateStatus(result, error_code);
695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// AboutChromeView, private:
698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AboutChromeView::UpdateStatus(GoogleUpdateUpgradeResult result,
700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   GoogleUpdateErrorCode error_code) {
701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(GOOGLE_CHROME_BUILD) && !defined(OS_CHROMEOS)
702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // For Chromium builds it would show an error message.
703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // But it looks weird because in fact there is no error,
704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // just the update server is not available for non-official builds.
705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return;
706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool show_success_indicator = false;
708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool show_update_available_indicator = false;
709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool show_timeout_indicator = false;
710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool show_throbber = false;
711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool show_update_label = true;  // Always visible, except at start.
712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (result) {
714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case UPGRADE_STARTED:
715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      UserMetrics::RecordAction(UserMetricsAction("Upgrade_Started"), profile_);
716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      show_throbber = true;
7173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      update_label_.SetText(
7183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen          UTF16ToWide(l10n_util::GetStringUTF16(IDS_UPGRADE_STARTED)));
719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case UPGRADE_CHECK_STARTED:
721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      UserMetrics::RecordAction(UserMetricsAction("UpgradeCheck_Started"),
722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                profile_);
723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      show_throbber = true;
7243f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      update_label_.SetText(
7253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen          UTF16ToWide(l10n_util::GetStringUTF16(IDS_UPGRADE_CHECK_STARTED)));
726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case UPGRADE_IS_AVAILABLE:
728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      UserMetrics::RecordAction(
729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          UserMetricsAction("UpgradeCheck_UpgradeIsAvailable"), profile_);
7303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      DCHECK(!google_updater_);  // Should have been nulled out already.
7313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      google_updater_ = new GoogleUpdate();
7323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      google_updater_->set_status_listener(this);
7333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      UpdateStatus(UPGRADE_STARTED, GOOGLE_UPDATE_NO_ERROR);
7343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      // CheckForUpdate(true,...) means perform upgrade if new version found.
7353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      google_updater_->CheckForUpdate(true, window());
7363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      // TODO(seanparent): Need to see if this code needs to change to
7373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      // force a machine restart.
7383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      return;
739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case UPGRADE_ALREADY_UP_TO_DATE: {
740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // The extra version check is necessary on Windows because the application
741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // may be already up to date on disk though the running app is still
742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // out of date. Chrome OS doesn't quite have this issue since the
743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // OS/App are updated together. If a newer version of the OS has been
744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // staged then UPGRADE_SUCESSFUL will be returned.
745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Google Update reported that Chrome is up-to-date. Now make sure that we
747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // are running the latest version and if not, notify the user by falling
748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // into the next case of UPGRADE_SUCCESSFUL.
74921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      BrowserDistribution* dist = BrowserDistribution::GetDistribution();
75072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      base::ThreadRestrictions::ScopedAllowIO allow_io;
75121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      scoped_ptr<Version> installed_version(
75221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          InstallUtil::GetChromeVersion(dist, false));
75372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if (!installed_version.get()) {
75472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        // User-level Chrome is not installed, check system-level.
75572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        installed_version.reset(InstallUtil::GetChromeVersion(dist, true));
75672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      }
75721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      scoped_ptr<Version> running_version(
75821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          Version::GetVersionFromString(current_version_));
759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (!installed_version.get() ||
7603f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen          (installed_version->CompareTo(*running_version) <= 0)) {
761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        UserMetrics::RecordAction(
763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            UserMetricsAction("UpgradeCheck_AlreadyUpToDate"), profile_);
764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
7653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        std::wstring update_label_text = UTF16ToWide(l10n_util::GetStringFUTF16(
7663f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen            IDS_UPGRADE_ALREADY_UP_TO_DATE,
7673f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen            l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)));
768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else
7693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        std::wstring update_label_text = l10n_util::GetStringFUTF16(
7703f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen            IDS_UPGRADE_ALREADY_UP_TO_DATE,
7713f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen            l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
7723f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen            ASCIIToUTF16(current_version_));
773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (base::i18n::IsRTL()) {
775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          update_label_text.push_back(
776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              static_cast<wchar_t>(base::i18n::kLeftToRightMark));
777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        update_label_.SetText(update_label_text);
779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        show_success_indicator = true;
780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // No break here as we want to notify user about upgrade if there is one.
785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case UPGRADE_SUCCESSFUL: {
787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (result == UPGRADE_ALREADY_UP_TO_DATE)
788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        UserMetrics::RecordAction(
789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            UserMetricsAction("UpgradeCheck_AlreadyUpgraded"), profile_);
790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      else
791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        UserMetrics::RecordAction(UserMetricsAction("UpgradeCheck_Upgraded"),
792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  profile_);
7933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      restart_button_visible_ = true;
7943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      const std::wstring& update_string =
7953f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen          UTF16ToWide(l10n_util::GetStringFUTF16(
79672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen              IDS_UPGRADE_SUCCESSFUL_RELAUNCH,
7973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen              l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)));
798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      update_label_.SetText(update_string);
799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      show_success_indicator = true;
800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case UPGRADE_ERROR:
803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      UserMetrics::RecordAction(UserMetricsAction("UpgradeCheck_Error"),
804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                profile_);
8053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      restart_button_visible_ = false;
80672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if (error_code != GOOGLE_UPDATE_DISABLED_BY_POLICY) {
80772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        update_label_.SetText(UTF16ToWide(
80872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            l10n_util::GetStringFUTF16Int(IDS_UPGRADE_ERROR, error_code)));
80972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      } else {
81072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        update_label_.SetText(UTF16ToWide(
81172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            l10n_util::GetStringUTF16(IDS_UPGRADE_DISABLED_BY_POLICY)));
81272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      }
813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      show_timeout_indicator = true;
814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default:
816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED();
817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  success_indicator_.SetVisible(show_success_indicator);
820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  update_available_indicator_.SetVisible(show_update_available_indicator);
821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  timeout_indicator_.SetVisible(show_timeout_indicator);
822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  update_label_.SetVisible(show_update_label);
823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  throbber_->SetVisible(show_throbber);
824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (show_throbber)
825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    throbber_->Start();
826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  else
827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    throbber_->Stop();
828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We have updated controls on the parent, so we need to update its layout.
83072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  parent()->Layout();
831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check button may have appeared/disappeared. We cannot call this during
833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ViewHierarchyChanged because the |window()| pointer hasn't been set yet.
834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (window())
835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GetDialogClientView()->UpdateDialogButtons();
836c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
839