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 25 namespace chromeos { 26 27 namespace { 28 29 // Default width/height of the dialog. 30 const int kDefaultWidth = 350; 31 const int kDefaultHeight = 100; 32 33 //////////////////////////////////////////////////////////////////////////////// 34 // Dialog for certificate enrollment. This displays the content from the 35 // certificate enrollment URI. 36 class 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 77 EnrollmentDialogView::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 89 EnrollmentDialogView::~EnrollmentDialogView() { 90 } 91 92 // static 93 void 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 107 int EnrollmentDialogView::GetDialogButtons() const { 108 return ui::DIALOG_BUTTON_CANCEL | ui::DIALOG_BUTTON_OK; 109 } 110 111 bool EnrollmentDialogView::Accept() { 112 accepted_ = true; 113 return true; 114 } 115 116 void 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(¶ms); 125 } 126 127 string16 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 134 ui::ModalType EnrollmentDialogView::GetModalType() const { 135 return ui::MODAL_TYPE_SYSTEM; 136 } 137 138 string16 EnrollmentDialogView::GetWindowTitle() const { 139 return l10n_util::GetStringUTF16(IDS_NETWORK_ENROLLMENT_HANDLER_TITLE); 140 } 141 142 gfx::Size EnrollmentDialogView::GetPreferredSize() { 143 return gfx::Size(kDefaultWidth, kDefaultHeight); 144 } 145 146 void 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 187 class 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 207 DialogEnrollmentDelegate::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 214 DialogEnrollmentDelegate::~DialogEnrollmentDelegate() {} 215 216 bool 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 248 EnrollmentDelegate* 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