- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / enrollment_dialog_view.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chromeos/enrollment_dialog_view.h"
6
7 #include "base/bind.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/extensions/extension_host.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/profiles/profile_manager.h"
12 #include "chrome/browser/ui/browser_navigator.h"
13 #include "chromeos/network/network_event_log.h"
14 #include "chromeos/network/network_state.h"
15 #include "chromeos/network/network_state_handler.h"
16 #include "content/public/common/page_transition_types.h"
17 #include "extensions/common/constants.h"
18 #include "grit/generated_resources.h"
19 #include "ui/base/l10n/l10n_util.h"
20 #include "ui/base/resource/resource_bundle.h"
21 #include "ui/views/controls/label.h"
22 #include "ui/views/layout/grid_layout.h"
23 #include "ui/views/layout/layout_constants.h"
24 #include "ui/views/widget/widget.h"
25 #include "ui/views/window/dialog_delegate.h"
26
27 namespace chromeos {
28
29 namespace {
30
31 // Default width/height of the dialog.
32 const int kDefaultWidth = 350;
33 const int kDefaultHeight = 100;
34
35 ////////////////////////////////////////////////////////////////////////////////
36 // Dialog for certificate enrollment. This displays the content from the
37 // certificate enrollment URI.
38 class EnrollmentDialogView : public views::DialogDelegateView {
39  public:
40   virtual ~EnrollmentDialogView();
41
42   static void ShowDialog(gfx::NativeWindow owning_window,
43                          const std::string& network_name,
44                          Profile* profile,
45                          const GURL& target_uri,
46                          const base::Closure& connect);
47
48   // views::DialogDelegateView overrides
49   virtual int GetDialogButtons() const OVERRIDE;
50   virtual bool Accept() OVERRIDE;
51   virtual void OnClosed() OVERRIDE;
52   virtual string16 GetDialogButtonLabel(ui::DialogButton button) const OVERRIDE;
53
54   // views::WidgetDelegate overrides
55   virtual ui::ModalType GetModalType() const OVERRIDE;
56   virtual string16 GetWindowTitle() const OVERRIDE;
57
58   // views::View overrides
59   virtual gfx::Size GetPreferredSize() OVERRIDE;
60
61  private:
62   EnrollmentDialogView(const std::string& network_name,
63                        Profile* profile,
64                        const GURL& target_uri,
65                        const base::Closure& connect);
66   void InitDialog();
67
68   bool accepted_;
69   std::string network_name_;
70   Profile* profile_;
71   GURL target_uri_;
72   base::Closure connect_;
73   bool added_cert_;
74 };
75
76 ////////////////////////////////////////////////////////////////////////////////
77 // EnrollmentDialogView implementation.
78
79 EnrollmentDialogView::EnrollmentDialogView(const std::string& network_name,
80                                            Profile* profile,
81                                            const GURL& target_uri,
82                                            const base::Closure& connect)
83     : accepted_(false),
84       network_name_(network_name),
85       profile_(profile),
86       target_uri_(target_uri),
87       connect_(connect),
88       added_cert_(false) {
89 }
90
91 EnrollmentDialogView::~EnrollmentDialogView() {
92 }
93
94 // static
95 void EnrollmentDialogView::ShowDialog(gfx::NativeWindow owning_window,
96                                       const std::string& network_name,
97                                       Profile* profile,
98                                       const GURL& target_uri,
99                                       const base::Closure& connect) {
100   EnrollmentDialogView* dialog_view =
101       new EnrollmentDialogView(network_name, profile, target_uri, connect);
102   views::DialogDelegate::CreateDialogWidget(dialog_view, NULL, owning_window);
103   dialog_view->InitDialog();
104   views::Widget* widget = dialog_view->GetWidget();
105   DCHECK(widget);
106   widget->Show();
107 }
108
109 int EnrollmentDialogView::GetDialogButtons() const {
110   return ui::DIALOG_BUTTON_CANCEL | ui::DIALOG_BUTTON_OK;
111 }
112
113 bool EnrollmentDialogView::Accept() {
114   accepted_ = true;
115   return true;
116 }
117
118 void EnrollmentDialogView::OnClosed() {
119   if (!accepted_)
120     return;
121   chrome::NavigateParams params(profile_,
122                                 GURL(target_uri_),
123                                 content::PAGE_TRANSITION_LINK);
124   params.disposition = NEW_FOREGROUND_TAB;
125   params.window_action = chrome::NavigateParams::SHOW_WINDOW;
126   chrome::Navigate(&params);
127 }
128
129 string16 EnrollmentDialogView::GetDialogButtonLabel(
130     ui::DialogButton button) const {
131   if (button == ui::DIALOG_BUTTON_OK)
132     return l10n_util::GetStringUTF16(IDS_NETWORK_ENROLLMENT_HANDLER_BUTTON);
133   return views::DialogDelegateView::GetDialogButtonLabel(button);
134 }
135
136 ui::ModalType EnrollmentDialogView::GetModalType() const {
137   return ui::MODAL_TYPE_SYSTEM;
138 }
139
140 string16 EnrollmentDialogView::GetWindowTitle() const {
141   return l10n_util::GetStringUTF16(IDS_NETWORK_ENROLLMENT_HANDLER_TITLE);
142 }
143
144 gfx::Size EnrollmentDialogView::GetPreferredSize() {
145   return gfx::Size(kDefaultWidth, kDefaultHeight);
146 }
147
148 void EnrollmentDialogView::InitDialog() {
149   added_cert_ = false;
150   // Create the views and layout manager and set them up.
151   views::Label* label = new views::Label(
152       l10n_util::GetStringFUTF16(IDS_NETWORK_ENROLLMENT_HANDLER_INSTRUCTIONS,
153                                  UTF8ToUTF16(network_name_)));
154   label->SetFont(ui::ResourceBundle::GetSharedInstance().GetFont(
155       ui::ResourceBundle::BaseFont));
156   label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
157   label->SetMultiLine(true);
158   label->SetAllowCharacterBreak(true);
159
160   views::GridLayout* grid_layout = views::GridLayout::CreatePanel(this);
161   SetLayoutManager(grid_layout);
162
163   views::ColumnSet* columns = grid_layout->AddColumnSet(0);
164   columns->AddColumn(views::GridLayout::FILL,  // Horizontal resize.
165                      views::GridLayout::FILL,  // Vertical resize.
166                      1,   // Resize weight.
167                      views::GridLayout::USE_PREF,  // Size type.
168                      0,   // Ignored for USE_PREF.
169                      0);  // Minimum size.
170   columns = grid_layout->AddColumnSet(1);
171   columns->AddPaddingColumn(
172       0, views::kUnrelatedControlHorizontalSpacing);
173   columns->AddColumn(views::GridLayout::LEADING,  // Horizontal leading.
174                      views::GridLayout::FILL,     // Vertical resize.
175                      1,   // Resize weight.
176                      views::GridLayout::USE_PREF,  // Size type.
177                      0,   // Ignored for USE_PREF.
178                      0);  // Minimum size.
179
180   grid_layout->StartRow(0, 0);
181   grid_layout->AddView(label);
182   grid_layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
183   grid_layout->Layout(this);
184 }
185
186 ////////////////////////////////////////////////////////////////////////////////
187 // Handler for certificate enrollment.
188
189 class DialogEnrollmentDelegate {
190  public:
191   // |owning_window| is the window that will own the dialog.
192   DialogEnrollmentDelegate(gfx::NativeWindow owning_window,
193                            const std::string& network_name,
194                            Profile* profile);
195   ~DialogEnrollmentDelegate();
196
197   // EnrollmentDelegate overrides
198   bool Enroll(const std::vector<std::string>& uri_list,
199               const base::Closure& connect);
200
201  private:
202   gfx::NativeWindow owning_window_;
203   std::string network_name_;
204   Profile* profile_;
205
206   DISALLOW_COPY_AND_ASSIGN(DialogEnrollmentDelegate);
207 };
208
209 DialogEnrollmentDelegate::DialogEnrollmentDelegate(
210     gfx::NativeWindow owning_window,
211     const std::string& network_name,
212     Profile* profile) : owning_window_(owning_window),
213                         network_name_(network_name),
214                         profile_(profile) {}
215
216 DialogEnrollmentDelegate::~DialogEnrollmentDelegate() {}
217
218 bool DialogEnrollmentDelegate::Enroll(const std::vector<std::string>& uri_list,
219                                       const base::Closure& post_action) {
220   if (uri_list.empty()) {
221     NET_LOG_EVENT("No enrollment URIs", network_name_);
222     return false;
223   }
224
225   // Keep the closure for later activation if we notice that
226   // a certificate has been added.
227
228   // TODO(gspencer): Do something smart with the closure.  At the moment it is
229   // being ignored because we don't know when the enrollment tab is closed.
230   // http://crosbug.com/30422
231   for (std::vector<std::string>::const_iterator iter = uri_list.begin();
232        iter != uri_list.end(); ++iter) {
233     GURL uri(*iter);
234     if (uri.IsStandard() || uri.scheme() == extensions::kExtensionScheme) {
235       // If this is a "standard" scheme, like http, ftp, etc., then open that in
236       // the enrollment dialog.
237       NET_LOG_EVENT("Showing enrollment dialog", network_name_);
238       EnrollmentDialogView::ShowDialog(owning_window_,
239                                        network_name_,
240                                        profile_,
241                                        uri, post_action);
242       return true;
243     }
244     NET_LOG_DEBUG("Nonstandard URI: " + uri.spec(), network_name_);
245   }
246
247   // No appropriate scheme was found.
248   NET_LOG_ERROR("No usable enrollment URI", network_name_);
249   return false;
250 }
251
252 void EnrollmentComplete(const std::string& service_path) {
253   NET_LOG_USER("Enrollment Complete", service_path);
254 }
255
256 }  // namespace
257
258 ////////////////////////////////////////////////////////////////////////////////
259 // Factory function.
260
261 namespace enrollment {
262
263 bool CreateDialog(const std::string& service_path,
264                   gfx::NativeWindow owning_window) {
265   const NetworkState* network = NetworkHandler::Get()->network_state_handler()->
266       GetNetworkState(service_path);
267   if (!network) {
268     NET_LOG_ERROR("Enrolling Unknown network", service_path);
269     return false;
270   }
271   // We skip certificate patterns for device policy ONC so that an unmanaged
272   // user can't get to the place where a cert is presented for them
273   // involuntarily.
274   if (network->ui_data().onc_source() == onc::ONC_SOURCE_DEVICE_POLICY)
275     return false;
276
277   const CertificatePattern& certificate_pattern =
278       network->ui_data().certificate_pattern();
279   if (certificate_pattern.Empty()) {
280     NET_LOG_EVENT("No certificate pattern found", service_path);
281     return false;
282   }
283
284   NET_LOG_USER("Enrolling", service_path);
285
286   DialogEnrollmentDelegate* enrollment =
287       new DialogEnrollmentDelegate(owning_window, network->name(),
288                                    ProfileManager::GetDefaultProfile());
289   return enrollment->Enroll(certificate_pattern.enrollment_uri_list(),
290                             base::Bind(&EnrollmentComplete, service_path));
291 }
292
293 }  // namespace enrollment
294
295 }  // namespace chromeos