enrollment_dialog_view.cc revision ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16
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/chromeos/enrollment_dialog_view.h"
6
7#include "base/bind.h"
8#include "base/strings/utf_string_conversions.h"
9#include "chrome/browser/chromeos/cros/network_library.h"
10#include "chrome/browser/extensions/extension_host.h"
11#include "chrome/browser/profiles/profile.h"
12#include "chrome/browser/ui/browser_navigator.h"
13#include "chromeos/network/network_event_log.h"
14#include "content/public/common/page_transition_types.h"
15#include "extensions/common/constants.h"
16#include "grit/generated_resources.h"
17#include "ui/base/l10n/l10n_util.h"
18#include "ui/base/resource/resource_bundle.h"
19#include "ui/views/controls/label.h"
20#include "ui/views/layout/grid_layout.h"
21#include "ui/views/layout/layout_constants.h"
22#include "ui/views/widget/widget.h"
23#include "ui/views/window/dialog_delegate.h"
24
25namespace chromeos {
26
27namespace {
28
29// Default width/height of the dialog.
30const int kDefaultWidth = 350;
31const int kDefaultHeight = 100;
32
33////////////////////////////////////////////////////////////////////////////////
34// Dialog for certificate enrollment. This displays the content from the
35// certificate enrollment URI.
36class EnrollmentDialogView : public views::DialogDelegateView {
37 public:
38  virtual ~EnrollmentDialogView();
39
40  static void ShowDialog(gfx::NativeWindow owning_window,
41                         const std::string& network_name,
42                         Profile* profile,
43                         const GURL& target_uri,
44                         const base::Closure& connect);
45
46  // views::DialogDelegateView overrides
47  virtual int GetDialogButtons() const OVERRIDE;
48  virtual bool Accept() OVERRIDE;
49  virtual void OnClosed() OVERRIDE;
50  virtual string16 GetDialogButtonLabel(ui::DialogButton button) const OVERRIDE;
51
52  // views::WidgetDelegate overrides
53  virtual ui::ModalType GetModalType() const OVERRIDE;
54  virtual string16 GetWindowTitle() const OVERRIDE;
55
56  // views::View overrides
57  virtual gfx::Size GetPreferredSize() OVERRIDE;
58
59 private:
60  EnrollmentDialogView(const std::string& network_name,
61                       Profile* profile,
62                       const GURL& target_uri,
63                       const base::Closure& connect);
64  void InitDialog();
65
66  bool accepted_;
67  std::string network_name_;
68  Profile* profile_;
69  GURL target_uri_;
70  base::Closure connect_;
71  bool added_cert_;
72};
73
74////////////////////////////////////////////////////////////////////////////////
75// EnrollmentDialogView implementation.
76
77EnrollmentDialogView::EnrollmentDialogView(const std::string& network_name,
78                                           Profile* profile,
79                                           const GURL& target_uri,
80                                           const base::Closure& connect)
81    : accepted_(false),
82      network_name_(network_name),
83      profile_(profile),
84      target_uri_(target_uri),
85      connect_(connect),
86      added_cert_(false) {
87}
88
89EnrollmentDialogView::~EnrollmentDialogView() {
90}
91
92// static
93void EnrollmentDialogView::ShowDialog(gfx::NativeWindow owning_window,
94                                      const std::string& network_name,
95                                      Profile* profile,
96                                      const GURL& target_uri,
97                                      const base::Closure& connect) {
98  EnrollmentDialogView* dialog_view =
99      new EnrollmentDialogView(network_name, profile, target_uri, connect);
100  views::DialogDelegate::CreateDialogWidget(dialog_view, NULL, owning_window);
101  dialog_view->InitDialog();
102  views::Widget* widget = dialog_view->GetWidget();
103  DCHECK(widget);
104  widget->Show();
105}
106
107int EnrollmentDialogView::GetDialogButtons() const {
108  return ui::DIALOG_BUTTON_CANCEL | ui::DIALOG_BUTTON_OK;
109}
110
111bool EnrollmentDialogView::Accept() {
112  accepted_ = true;
113  return true;
114}
115
116void EnrollmentDialogView::OnClosed() {
117  if (!accepted_)
118    return;
119  chrome::NavigateParams params(profile_,
120                                GURL(target_uri_),
121                                content::PAGE_TRANSITION_LINK);
122  params.disposition = NEW_FOREGROUND_TAB;
123  params.window_action = chrome::NavigateParams::SHOW_WINDOW;
124  chrome::Navigate(&params);
125}
126
127string16 EnrollmentDialogView::GetDialogButtonLabel(
128    ui::DialogButton button) const {
129  if (button == ui::DIALOG_BUTTON_OK)
130    return l10n_util::GetStringUTF16(IDS_NETWORK_ENROLLMENT_HANDLER_BUTTON);
131  return views::DialogDelegateView::GetDialogButtonLabel(button);
132}
133
134ui::ModalType EnrollmentDialogView::GetModalType() const {
135  return ui::MODAL_TYPE_SYSTEM;
136}
137
138string16 EnrollmentDialogView::GetWindowTitle() const {
139  return l10n_util::GetStringUTF16(IDS_NETWORK_ENROLLMENT_HANDLER_TITLE);
140}
141
142gfx::Size EnrollmentDialogView::GetPreferredSize() {
143  return gfx::Size(kDefaultWidth, kDefaultHeight);
144}
145
146void EnrollmentDialogView::InitDialog() {
147  added_cert_ = false;
148  // Create the views and layout manager and set them up.
149  views::Label* label = new views::Label(
150      l10n_util::GetStringFUTF16(IDS_NETWORK_ENROLLMENT_HANDLER_INSTRUCTIONS,
151                                 UTF8ToUTF16(network_name_)));
152  label->SetFont(ui::ResourceBundle::GetSharedInstance().GetFont(
153      ui::ResourceBundle::BaseFont));
154  label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
155  label->SetMultiLine(true);
156  label->SetAllowCharacterBreak(true);
157
158  views::GridLayout* grid_layout = views::GridLayout::CreatePanel(this);
159  SetLayoutManager(grid_layout);
160
161  views::ColumnSet* columns = grid_layout->AddColumnSet(0);
162  columns->AddColumn(views::GridLayout::FILL,  // Horizontal resize.
163                     views::GridLayout::FILL,  // Vertical resize.
164                     1,   // Resize weight.
165                     views::GridLayout::USE_PREF,  // Size type.
166                     0,   // Ignored for USE_PREF.
167                     0);  // Minimum size.
168  columns = grid_layout->AddColumnSet(1);
169  columns->AddPaddingColumn(
170      0, views::kUnrelatedControlHorizontalSpacing);
171  columns->AddColumn(views::GridLayout::LEADING,  // Horizontal leading.
172                     views::GridLayout::FILL,     // Vertical resize.
173                     1,   // Resize weight.
174                     views::GridLayout::USE_PREF,  // Size type.
175                     0,   // Ignored for USE_PREF.
176                     0);  // Minimum size.
177
178  grid_layout->StartRow(0, 0);
179  grid_layout->AddView(label);
180  grid_layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
181  grid_layout->Layout(this);
182}
183
184////////////////////////////////////////////////////////////////////////////////
185// Handler for certificate enrollment.
186
187class DialogEnrollmentDelegate : public EnrollmentDelegate {
188 public:
189  // |owning_window| is the window that will own the dialog.
190  explicit DialogEnrollmentDelegate(gfx::NativeWindow owning_window,
191                                    const std::string& network_name,
192                                    Profile* profile);
193  virtual ~DialogEnrollmentDelegate();
194
195  // EnrollmentDelegate overrides
196  virtual bool Enroll(const std::vector<std::string>& uri_list,
197                      const base::Closure& connect) OVERRIDE;
198
199 private:
200  gfx::NativeWindow owning_window_;
201  std::string network_name_;
202  Profile* profile_;
203
204  DISALLOW_COPY_AND_ASSIGN(DialogEnrollmentDelegate);
205};
206
207DialogEnrollmentDelegate::DialogEnrollmentDelegate(
208    gfx::NativeWindow owning_window,
209    const std::string& network_name,
210    Profile* profile) : owning_window_(owning_window),
211                        network_name_(network_name),
212                        profile_(profile) {}
213
214DialogEnrollmentDelegate::~DialogEnrollmentDelegate() {}
215
216bool DialogEnrollmentDelegate::Enroll(const std::vector<std::string>& uri_list,
217                                      const base::Closure& post_action) {
218  // Keep the closure for later activation if we notice that
219  // a certificate has been added.
220
221  // TODO(gspencer): Do something smart with the closure.  At the moment it is
222  // being ignored because we don't know when the enrollment tab is closed.
223  // http://crosbug.com/30422
224  for (std::vector<std::string>::const_iterator iter = uri_list.begin();
225       iter != uri_list.end(); ++iter) {
226    GURL uri(*iter);
227    if (uri.IsStandard() || uri.scheme() == extensions::kExtensionScheme) {
228      // If this is a "standard" scheme, like http, ftp, etc., then open that in
229      // the enrollment dialog.
230      EnrollmentDialogView::ShowDialog(owning_window_,
231                                       network_name_,
232                                       profile_,
233                                       uri, post_action);
234      return true;
235    }
236  }
237
238  // No appropriate scheme was found.
239  NET_LOG_EVENT("No usable enrollment URI", network_name_);
240  return false;
241}
242
243}  // namespace
244
245////////////////////////////////////////////////////////////////////////////////
246// Factory function.
247
248EnrollmentDelegate* CreateEnrollmentDelegate(gfx::NativeWindow owning_window,
249                                             const std::string& network_name,
250                                             Profile* profile) {
251  return new DialogEnrollmentDelegate(owning_window, network_name, profile);
252}
253
254}  // namespace chromeos
255