Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / options / network_config_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/options/network_config_view.h"
6
7 #include <algorithm>
8
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/chromium_strings.h"
23 #include "chrome/grit/generated_resources.h"
24 #include "chrome/grit/locale_settings.h"
25 #include "chrome/grit/theme_resources.h"
26 #include "chromeos/login/login_state.h"
27 #include "chromeos/network/network_state.h"
28 #include "chromeos/network/network_state_handler.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/image/image.h"
35 #include "ui/gfx/rect.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"
40
41 using views::Widget;
42
43 namespace {
44
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();
55   }
56   return NULL;
57 }
58
59 // Avoid global static initializer.
60 chromeos::NetworkConfigView** GetActiveDialogPointer() {
61   static chromeos::NetworkConfigView* active_dialog = NULL;
62   return &active_dialog;
63 }
64
65 chromeos::NetworkConfigView* GetActiveDialog() {
66   return *(GetActiveDialogPointer());
67 }
68
69 void SetActiveDialog(chromeos::NetworkConfigView* dialog) {
70   *(GetActiveDialogPointer()) = dialog;
71 }
72
73 }  // namespace
74
75 namespace chromeos {
76
77 // static
78 const int ChildNetworkConfigView::kInputFieldMinWidth = 270;
79
80 NetworkConfigView::NetworkConfigView()
81     : child_config_view_(NULL),
82       delegate_(NULL),
83       advanced_button_(NULL) {
84   DCHECK(GetActiveDialog() == NULL);
85   SetActiveDialog(this);
86 }
87
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);
98   }
99   return child_config_view_ != NULL;
100 }
101
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 */);
113   }
114   return child_config_view_ != NULL;
115 }
116
117 NetworkConfigView::~NetworkConfigView() {
118   DCHECK(GetActiveDialog() == this);
119   SetActiveDialog(NULL);
120 }
121
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;
133   }
134   if (!view->InitWithNetworkState(network)) {
135     LOG(ERROR) << "NetworkConfigView::Show called with invalid network type: "
136                << network->type();
137     delete view;
138     return;
139   }
140   view->ShowDialog(parent);
141 }
142
143 // static
144 void NetworkConfigView::ShowForType(const std::string& type,
145                                     gfx::NativeWindow parent) {
146   if (GetActiveDialog() != NULL)
147     return;
148   NetworkConfigView* view = new NetworkConfigView();
149   if (!view->InitWithType(type)) {
150     LOG(ERROR) << "NetworkConfigView::ShowForType called with invalid type: "
151                << type;
152     delete view;
153     return;
154   }
155   view->ShowDialog(parent);
156 }
157
158 gfx::NativeWindow NetworkConfigView::GetNativeWindow() const {
159   return GetWidget()->GetNativeWindow();
160 }
161
162 base::string16 NetworkConfigView::GetDialogButtonLabel(
163     ui::DialogButton button) const {
164   if (button == ui::DIALOG_BUTTON_OK) {
165     if (child_config_view_->IsConfigureDialog())
166       return l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_CONFIGURE);
167     return l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_CONNECT);
168   }
169   return views::DialogDelegateView::GetDialogButtonLabel(button);
170 }
171
172 bool NetworkConfigView::IsDialogButtonEnabled(ui::DialogButton button) const {
173   // Disable connect button if cannot login.
174   if (button == ui::DIALOG_BUTTON_OK)
175     return child_config_view_->CanLogin();
176   return true;
177 }
178
179 bool NetworkConfigView::Cancel() {
180   if (delegate_)
181     delegate_->OnDialogCancelled();
182   child_config_view_->Cancel();
183   return true;
184 }
185
186 bool NetworkConfigView::Accept() {
187   // Do not attempt login if it is guaranteed to fail, keep the dialog open.
188   if (!child_config_view_->CanLogin())
189     return false;
190   bool result = child_config_view_->Login();
191   if (result && delegate_)
192     delegate_->OnDialogAccepted();
193   return result;
194 }
195
196 views::View* NetworkConfigView::CreateExtraView() {
197   return advanced_button_;
198 }
199
200 views::View* NetworkConfigView::GetInitiallyFocusedView() {
201   return child_config_view_->GetInitiallyFocusedView();
202 }
203
204 base::string16 NetworkConfigView::GetWindowTitle() const {
205   DCHECK(!child_config_view_->GetTitle().empty());
206   return child_config_view_->GetTitle();
207 }
208
209 ui::ModalType NetworkConfigView::GetModalType() const {
210   return ui::MODAL_TYPE_SYSTEM;
211 }
212
213 void NetworkConfigView::GetAccessibleState(ui::AXViewState* state) {
214   state->name =
215       l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_OTHER_WIFI_NETWORKS);
216   state->role = ui::AX_ROLE_DIALOG;
217 }
218
219 void NetworkConfigView::ButtonPressed(views::Button* sender,
220                                       const ui::Event& event) {
221   if (advanced_button_ && sender == advanced_button_) {
222     advanced_button_->SetVisible(false);
223     ShowAdvancedView();
224   }
225 }
226
227 void NetworkConfigView::ShowAdvancedView() {
228   // Clear out the old widgets and build new ones.
229   RemoveChildView(child_config_view_);
230   delete child_config_view_;
231   // For now, there is only an advanced view for Wi-Fi 802.1X.
232   child_config_view_ = new WifiConfigView(this,
233                                           "" /* service_path */,
234                                           true /* show_8021x */);
235   AddChildView(child_config_view_);
236   // Resize the window to be able to hold the new widgets.
237   gfx::Size size = views::Widget::GetLocalizedContentsSize(
238       IDS_JOIN_WIFI_NETWORK_DIALOG_ADVANCED_WIDTH_CHARS,
239       IDS_JOIN_WIFI_NETWORK_DIALOG_ADVANCED_MINIMUM_HEIGHT_LINES);
240   // Get the new bounds with desired size at the same center point.
241   gfx::Rect bounds = GetWidget()->GetWindowBoundsInScreen();
242   int horiz_padding = bounds.width() - size.width();
243   int vert_padding = bounds.height() - size.height();
244   bounds.Inset(horiz_padding / 2, vert_padding / 2,
245                horiz_padding / 2, vert_padding / 2);
246   GetWidget()->SetBoundsConstrained(bounds);
247   Layout();
248   child_config_view_->InitFocus();
249 }
250
251 void NetworkConfigView::Layout() {
252   child_config_view_->SetBounds(0, 0, width(), height());
253 }
254
255 gfx::Size NetworkConfigView::GetPreferredSize() const {
256   gfx::Size result(views::Widget::GetLocalizedContentsSize(
257       IDS_JOIN_WIFI_NETWORK_DIALOG_WIDTH_CHARS,
258       IDS_JOIN_WIFI_NETWORK_DIALOG_MINIMUM_HEIGHT_LINES));
259   gfx::Size size = child_config_view_->GetPreferredSize();
260   result.set_height(size.height());
261   if (size.width() > result.width())
262     result.set_width(size.width());
263   return result;
264 }
265
266 void NetworkConfigView::ViewHierarchyChanged(
267     const ViewHierarchyChangedDetails& details) {
268   // Can't init before we're inserted into a Container, because we require
269   // a HWND to parent native child controls to.
270   if (details.is_add && details.child == this) {
271     AddChildView(child_config_view_);
272   }
273 }
274
275 void NetworkConfigView::ShowDialog(gfx::NativeWindow parent) {
276   if (parent == NULL)
277     parent = GetParentForUnhostedDialog();
278   // Failed connections may result in a pop-up with no natural parent window,
279   // so provide a fallback context on the primary display. This is necessary
280   // becase one of parent or context must be non NULL.
281   gfx::NativeWindow context =
282       parent ? NULL : ash::Shell::GetPrimaryRootWindow();
283   Widget* window = DialogDelegate::CreateDialogWidget(this, context, parent);
284   window->SetAlwaysOnTop(true);
285   window->Show();
286 }
287
288 // ChildNetworkConfigView
289
290 ChildNetworkConfigView::ChildNetworkConfigView(
291     NetworkConfigView* parent,
292     const std::string& service_path)
293     : parent_(parent),
294       service_path_(service_path) {
295 }
296
297 ChildNetworkConfigView::~ChildNetworkConfigView() {
298 }
299
300 bool ChildNetworkConfigView::IsConfigureDialog() {
301   return false;
302 }
303
304 // static
305 void ChildNetworkConfigView::GetShareStateForLoginState(bool* default_value,
306                                                         bool* modifiable) {
307   *default_value = !LoginState::Get()->UserHasNetworkProfile();
308   // Allow only authenticated user to change the share state.
309   *modifiable = LoginState::Get()->IsUserAuthenticated();
310 }
311
312 // ControlledSettingIndicatorView
313
314 ControlledSettingIndicatorView::ControlledSettingIndicatorView()
315     : managed_(false),
316       image_view_(NULL) {
317   Init();
318 }
319
320 ControlledSettingIndicatorView::ControlledSettingIndicatorView(
321     const NetworkPropertyUIData& ui_data)
322     : managed_(false),
323       image_view_(NULL) {
324   Init();
325   Update(ui_data);
326 }
327
328 ControlledSettingIndicatorView::~ControlledSettingIndicatorView() {}
329
330 void ControlledSettingIndicatorView::Update(
331     const NetworkPropertyUIData& ui_data) {
332   if (managed_ == ui_data.IsManaged())
333     return;
334
335   managed_ = ui_data.IsManaged();
336   PreferredSizeChanged();
337 }
338
339 gfx::Size ControlledSettingIndicatorView::GetPreferredSize() const {
340   return (managed_ && visible()) ? image_view_->GetPreferredSize()
341                                  : gfx::Size();
342 }
343
344 void ControlledSettingIndicatorView::Layout() {
345   image_view_->SetBounds(0, 0, width(), height());
346 }
347
348 void ControlledSettingIndicatorView::Init() {
349   image_ = ResourceBundle::GetSharedInstance().GetImageNamed(
350       IDR_CONTROLLED_SETTING_MANDATORY).ToImageSkia();
351   image_view_ = new views::ImageView();
352   // Disable |image_view_| so mouse events propagate to the parent.
353   image_view_->SetEnabled(false);
354   image_view_->SetImage(image_);
355   image_view_->SetTooltipText(
356       l10n_util::GetStringUTF16(IDS_OPTIONS_CONTROLLED_SETTING_POLICY));
357   AddChildView(image_view_);
358 }
359
360 }  // namespace chromeos