Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / chromeos / options / network_config_view.cc
bloba5587f4a0ed6fd32f1c4f4b4425422fa2d2b0c5b
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/options/network_config_view.h"
7 #include <algorithm>
9 #include "ash/shell.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
13 #include "chrome/browser/chromeos/options/network_property_ui_data.h"
14 #include "chrome/browser/chromeos/options/vpn_config_view.h"
15 #include "chrome/browser/chromeos/options/wifi_config_view.h"
16 #include "chrome/browser/chromeos/options/wimax_config_view.h"
17 #include "chrome/browser/profiles/profile_manager.h"
18 #include "chrome/browser/ui/browser.h"
19 #include "chrome/browser/ui/browser_finder.h"
20 #include "chrome/browser/ui/browser_window.h"
21 #include "chrome/browser/ui/host_desktop.h"
22 #include "chrome/grit/generated_resources.h"
23 #include "chrome/grit/locale_settings.h"
24 #include "chrome/grit/theme_resources.h"
25 #include "chromeos/login/login_state.h"
26 #include "chromeos/network/network_state.h"
27 #include "chromeos/network/network_state_handler.h"
28 #include "components/device_event_log/device_event_log.h"
29 #include "components/user_manager/user.h"
30 #include "ui/accessibility/ax_view_state.h"
31 #include "ui/aura/window_event_dispatcher.h"
32 #include "ui/base/l10n/l10n_util.h"
33 #include "ui/base/resource/resource_bundle.h"
34 #include "ui/gfx/geometry/rect.h"
35 #include "ui/gfx/image/image.h"
36 #include "ui/views/controls/button/label_button.h"
37 #include "ui/views/controls/image_view.h"
38 #include "ui/views/layout/layout_constants.h"
39 #include "ui/views/widget/widget.h"
41 using views::Widget;
43 namespace {
45 gfx::NativeWindow GetParentForUnhostedDialog() {
46 if (chromeos::LoginDisplayHostImpl::default_host()) {
47 return chromeos::LoginDisplayHostImpl::default_host()->GetNativeWindow();
48 } else {
49 Browser* browser = chrome::FindTabbedBrowser(
50 ProfileManager::GetPrimaryUserProfile(),
51 true,
52 chrome::HOST_DESKTOP_TYPE_ASH);
53 if (browser)
54 return browser->window()->GetNativeWindow();
56 return NULL;
59 // Avoid global static initializer.
60 chromeos::NetworkConfigView** GetActiveDialogPointer() {
61 static chromeos::NetworkConfigView* active_dialog = NULL;
62 return &active_dialog;
65 chromeos::NetworkConfigView* GetActiveDialog() {
66 return *(GetActiveDialogPointer());
69 void SetActiveDialog(chromeos::NetworkConfigView* dialog) {
70 *(GetActiveDialogPointer()) = dialog;
73 } // namespace
75 namespace chromeos {
77 // static
78 const int ChildNetworkConfigView::kInputFieldMinWidth = 270;
80 NetworkConfigView::NetworkConfigView()
81 : child_config_view_(NULL),
82 delegate_(NULL),
83 advanced_button_(NULL) {
84 DCHECK(GetActiveDialog() == NULL);
85 SetActiveDialog(this);
88 bool NetworkConfigView::InitWithNetworkState(const NetworkState* network) {
89 DCHECK(network);
90 std::string service_path = network->path();
91 if (network->type() == shill::kTypeWifi ||
92 network->type() == shill::kTypeEthernet) {
93 child_config_view_ = new WifiConfigView(this, service_path, false);
94 } else if (network->type() == shill::kTypeWimax) {
95 child_config_view_ = new WimaxConfigView(this, service_path);
96 } else if (network->type() == shill::kTypeVPN) {
97 child_config_view_ = new VPNConfigView(this, service_path);
99 return child_config_view_ != NULL;
102 bool NetworkConfigView::InitWithType(const std::string& type) {
103 if (type == shill::kTypeWifi) {
104 child_config_view_ = new WifiConfigView(this,
105 "" /* service_path */,
106 false /* show_8021x */);
107 advanced_button_ = new views::LabelButton(this, l10n_util::GetStringUTF16(
108 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_ADVANCED_BUTTON));
109 advanced_button_->SetStyle(views::Button::STYLE_BUTTON);
110 } else if (type == shill::kTypeVPN) {
111 child_config_view_ = new VPNConfigView(this,
112 "" /* service_path */);
114 return child_config_view_ != NULL;
117 NetworkConfigView::~NetworkConfigView() {
118 DCHECK(GetActiveDialog() == this);
119 SetActiveDialog(NULL);
122 // static
123 void NetworkConfigView::Show(const std::string& service_path,
124 gfx::NativeWindow parent) {
125 if (GetActiveDialog() != NULL)
126 return;
127 NetworkConfigView* view = new NetworkConfigView();
128 const NetworkState* network = NetworkHandler::Get()->network_state_handler()->
129 GetNetworkState(service_path);
130 if (!network) {
131 LOG(ERROR) << "NetworkConfigView::Show called with invalid service_path";
132 return;
134 if (!view->InitWithNetworkState(network)) {
135 LOG(ERROR) << "NetworkConfigView::Show called with invalid network type: "
136 << network->type();
137 delete view;
138 return;
140 NET_LOG(USER) << "NetworkConfigView::Show: " << service_path;
141 view->ShowDialog(parent);
144 // static
145 void NetworkConfigView::ShowForType(const std::string& type,
146 gfx::NativeWindow parent) {
147 if (GetActiveDialog() != NULL)
148 return;
149 NetworkConfigView* view = new NetworkConfigView();
150 if (!view->InitWithType(type)) {
151 LOG(ERROR) << "NetworkConfigView::ShowForType called with invalid type: "
152 << type;
153 delete view;
154 return;
156 NET_LOG(USER) << "NetworkConfigView::ShowForType: " << type;
157 view->ShowDialog(parent);
160 gfx::NativeWindow NetworkConfigView::GetNativeWindow() const {
161 return GetWidget()->GetNativeWindow();
164 base::string16 NetworkConfigView::GetDialogButtonLabel(
165 ui::DialogButton button) const {
166 if (button == ui::DIALOG_BUTTON_OK) {
167 if (child_config_view_->IsConfigureDialog())
168 return l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_CONFIGURE);
169 return l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_CONNECT);
171 return views::DialogDelegateView::GetDialogButtonLabel(button);
174 bool NetworkConfigView::IsDialogButtonEnabled(ui::DialogButton button) const {
175 // Disable connect button if cannot login.
176 if (button == ui::DIALOG_BUTTON_OK)
177 return child_config_view_->CanLogin();
178 return true;
181 bool NetworkConfigView::Cancel() {
182 if (delegate_)
183 delegate_->OnDialogCancelled();
184 child_config_view_->Cancel();
185 return true;
188 bool NetworkConfigView::Accept() {
189 // Do not attempt login if it is guaranteed to fail, keep the dialog open.
190 if (!child_config_view_->CanLogin())
191 return false;
192 bool result = child_config_view_->Login();
193 if (result && delegate_)
194 delegate_->OnDialogAccepted();
195 return result;
198 views::View* NetworkConfigView::CreateExtraView() {
199 return advanced_button_;
202 views::View* NetworkConfigView::GetInitiallyFocusedView() {
203 return child_config_view_->GetInitiallyFocusedView();
206 base::string16 NetworkConfigView::GetWindowTitle() const {
207 DCHECK(!child_config_view_->GetTitle().empty());
208 return child_config_view_->GetTitle();
211 ui::ModalType NetworkConfigView::GetModalType() const {
212 return ui::MODAL_TYPE_SYSTEM;
215 void NetworkConfigView::GetAccessibleState(ui::AXViewState* state) {
216 views::DialogDelegateView::GetAccessibleState(state);
217 state->name =
218 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_OTHER_WIFI_NETWORKS);
221 void NetworkConfigView::ButtonPressed(views::Button* sender,
222 const ui::Event& event) {
223 if (advanced_button_ && sender == advanced_button_) {
224 advanced_button_->SetVisible(false);
225 ShowAdvancedView();
229 void NetworkConfigView::ShowAdvancedView() {
230 // Clear out the old widgets and build new ones.
231 RemoveChildView(child_config_view_);
232 delete child_config_view_;
233 // For now, there is only an advanced view for Wi-Fi 802.1X.
234 child_config_view_ = new WifiConfigView(this,
235 "" /* service_path */,
236 true /* show_8021x */);
237 AddChildView(child_config_view_);
238 // Resize the window to be able to hold the new widgets.
239 gfx::Size size = views::Widget::GetLocalizedContentsSize(
240 IDS_JOIN_WIFI_NETWORK_DIALOG_ADVANCED_WIDTH_CHARS,
241 IDS_JOIN_WIFI_NETWORK_DIALOG_ADVANCED_MINIMUM_HEIGHT_LINES);
242 // Get the new bounds with desired size at the same center point.
243 gfx::Rect bounds = GetWidget()->GetWindowBoundsInScreen();
244 int horiz_padding = bounds.width() - size.width();
245 int vert_padding = bounds.height() - size.height();
246 bounds.Inset(horiz_padding / 2, vert_padding / 2,
247 horiz_padding / 2, vert_padding / 2);
248 GetWidget()->SetBoundsConstrained(bounds);
249 Layout();
250 child_config_view_->InitFocus();
253 void NetworkConfigView::Layout() {
254 child_config_view_->SetBounds(0, 0, width(), height());
257 gfx::Size NetworkConfigView::GetPreferredSize() const {
258 gfx::Size result(views::Widget::GetLocalizedContentsSize(
259 IDS_JOIN_WIFI_NETWORK_DIALOG_WIDTH_CHARS,
260 IDS_JOIN_WIFI_NETWORK_DIALOG_MINIMUM_HEIGHT_LINES));
261 gfx::Size size = child_config_view_->GetPreferredSize();
262 result.set_height(size.height());
263 if (size.width() > result.width())
264 result.set_width(size.width());
265 return result;
268 void NetworkConfigView::ViewHierarchyChanged(
269 const ViewHierarchyChangedDetails& details) {
270 // Can't init before we're inserted into a Container, because we require
271 // a HWND to parent native child controls to.
272 views::DialogDelegateView::ViewHierarchyChanged(details);
273 if (details.is_add && details.child == this) {
274 AddChildView(child_config_view_);
278 void NetworkConfigView::ShowDialog(gfx::NativeWindow parent) {
279 if (parent == NULL)
280 parent = GetParentForUnhostedDialog();
281 // Failed connections may result in a pop-up with no natural parent window,
282 // so provide a fallback context on the primary display. This is necessary
283 // becase one of parent or context must be non NULL.
284 gfx::NativeWindow context =
285 parent ? NULL : ash::Shell::GetPrimaryRootWindow();
286 Widget* window = DialogDelegate::CreateDialogWidget(this, context, parent);
287 window->SetAlwaysOnTop(true);
288 window->Show();
291 // ChildNetworkConfigView
293 ChildNetworkConfigView::ChildNetworkConfigView(
294 NetworkConfigView* parent,
295 const std::string& service_path)
296 : parent_(parent),
297 service_path_(service_path) {
300 ChildNetworkConfigView::~ChildNetworkConfigView() {
303 bool ChildNetworkConfigView::IsConfigureDialog() {
304 return false;
307 // static
308 void ChildNetworkConfigView::GetShareStateForLoginState(bool* default_value,
309 bool* modifiable) {
310 *default_value = !LoginState::Get()->UserHasNetworkProfile();
311 // Allow only authenticated user to change the share state.
312 *modifiable = LoginState::Get()->IsUserAuthenticated();
315 // ControlledSettingIndicatorView
317 ControlledSettingIndicatorView::ControlledSettingIndicatorView()
318 : managed_(false),
319 image_view_(NULL) {
320 Init();
323 ControlledSettingIndicatorView::ControlledSettingIndicatorView(
324 const NetworkPropertyUIData& ui_data)
325 : managed_(false),
326 image_view_(NULL) {
327 Init();
328 Update(ui_data);
331 ControlledSettingIndicatorView::~ControlledSettingIndicatorView() {}
333 void ControlledSettingIndicatorView::Update(
334 const NetworkPropertyUIData& ui_data) {
335 if (managed_ == ui_data.IsManaged())
336 return;
338 managed_ = ui_data.IsManaged();
339 PreferredSizeChanged();
342 gfx::Size ControlledSettingIndicatorView::GetPreferredSize() const {
343 return (managed_ && visible()) ? image_view_->GetPreferredSize()
344 : gfx::Size();
347 void ControlledSettingIndicatorView::Layout() {
348 image_view_->SetBounds(0, 0, width(), height());
351 void ControlledSettingIndicatorView::Init() {
352 image_ = ResourceBundle::GetSharedInstance()
353 .GetImageNamed(IDR_OMNIBOX_HTTPS_POLICY_WARNING)
354 .ToImageSkia();
355 image_view_ = new views::ImageView();
356 // Disable |image_view_| so mouse events propagate to the parent.
357 image_view_->SetEnabled(false);
358 image_view_->SetImage(image_);
359 image_view_->SetTooltipText(
360 l10n_util::GetStringUTF16(IDS_OPTIONS_CONTROLLED_SETTING_POLICY));
361 AddChildView(image_view_);
364 } // namespace chromeos