1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/enrollment_dialog_view.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"
31 // Default width/height of the dialog.
32 const int kDefaultWidth = 350;
33 const int kDefaultHeight = 100;
35 ////////////////////////////////////////////////////////////////////////////////
36 // Dialog for certificate enrollment. This displays the content from the
37 // certificate enrollment URI.
38 class EnrollmentDialogView : public views::DialogDelegateView {
40 virtual ~EnrollmentDialogView();
42 static void ShowDialog(gfx::NativeWindow owning_window,
43 const std::string& network_name,
45 const GURL& target_uri,
46 const base::Closure& connect);
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;
54 // views::WidgetDelegate overrides
55 virtual ui::ModalType GetModalType() const OVERRIDE;
56 virtual string16 GetWindowTitle() const OVERRIDE;
58 // views::View overrides
59 virtual gfx::Size GetPreferredSize() OVERRIDE;
62 EnrollmentDialogView(const std::string& network_name,
64 const GURL& target_uri,
65 const base::Closure& connect);
69 std::string network_name_;
72 base::Closure connect_;
76 ////////////////////////////////////////////////////////////////////////////////
77 // EnrollmentDialogView implementation.
79 EnrollmentDialogView::EnrollmentDialogView(const std::string& network_name,
81 const GURL& target_uri,
82 const base::Closure& connect)
84 network_name_(network_name),
86 target_uri_(target_uri),
91 EnrollmentDialogView::~EnrollmentDialogView() {
95 void EnrollmentDialogView::ShowDialog(gfx::NativeWindow owning_window,
96 const std::string& network_name,
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();
109 int EnrollmentDialogView::GetDialogButtons() const {
110 return ui::DIALOG_BUTTON_CANCEL | ui::DIALOG_BUTTON_OK;
113 bool EnrollmentDialogView::Accept() {
118 void EnrollmentDialogView::OnClosed() {
121 chrome::NavigateParams params(profile_,
123 content::PAGE_TRANSITION_LINK);
124 params.disposition = NEW_FOREGROUND_TAB;
125 params.window_action = chrome::NavigateParams::SHOW_WINDOW;
126 chrome::Navigate(¶ms);
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);
136 ui::ModalType EnrollmentDialogView::GetModalType() const {
137 return ui::MODAL_TYPE_SYSTEM;
140 string16 EnrollmentDialogView::GetWindowTitle() const {
141 return l10n_util::GetStringUTF16(IDS_NETWORK_ENROLLMENT_HANDLER_TITLE);
144 gfx::Size EnrollmentDialogView::GetPreferredSize() {
145 return gfx::Size(kDefaultWidth, kDefaultHeight);
148 void EnrollmentDialogView::InitDialog() {
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);
160 views::GridLayout* grid_layout = views::GridLayout::CreatePanel(this);
161 SetLayoutManager(grid_layout);
163 views::ColumnSet* columns = grid_layout->AddColumnSet(0);
164 columns->AddColumn(views::GridLayout::FILL, // Horizontal resize.
165 views::GridLayout::FILL, // Vertical resize.
167 views::GridLayout::USE_PREF, // Size type.
168 0, // Ignored for USE_PREF.
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.
176 views::GridLayout::USE_PREF, // Size type.
177 0, // Ignored for USE_PREF.
180 grid_layout->StartRow(0, 0);
181 grid_layout->AddView(label);
182 grid_layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
183 grid_layout->Layout(this);
186 ////////////////////////////////////////////////////////////////////////////////
187 // Handler for certificate enrollment.
189 class DialogEnrollmentDelegate {
191 // |owning_window| is the window that will own the dialog.
192 DialogEnrollmentDelegate(gfx::NativeWindow owning_window,
193 const std::string& network_name,
195 ~DialogEnrollmentDelegate();
197 // EnrollmentDelegate overrides
198 bool Enroll(const std::vector<std::string>& uri_list,
199 const base::Closure& connect);
202 gfx::NativeWindow owning_window_;
203 std::string network_name_;
206 DISALLOW_COPY_AND_ASSIGN(DialogEnrollmentDelegate);
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),
216 DialogEnrollmentDelegate::~DialogEnrollmentDelegate() {}
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_);
225 // Keep the closure for later activation if we notice that
226 // a certificate has been added.
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) {
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_,
244 NET_LOG_DEBUG("Nonstandard URI: " + uri.spec(), network_name_);
247 // No appropriate scheme was found.
248 NET_LOG_ERROR("No usable enrollment URI", network_name_);
252 void EnrollmentComplete(const std::string& service_path) {
253 NET_LOG_USER("Enrollment Complete", service_path);
258 ////////////////////////////////////////////////////////////////////////////////
261 namespace enrollment {
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);
268 NET_LOG_ERROR("Enrolling Unknown network", service_path);
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
274 if (network->ui_data().onc_source() == onc::ONC_SOURCE_DEVICE_POLICY)
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);
284 NET_LOG_USER("Enrolling", service_path);
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));
293 } // namespace enrollment
295 } // namespace chromeos