1 // Copyright (c) 2011 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/network_login_observer.h"
6
7 #include "chrome/browser/chromeos/cros/cros_library.h"
8 #include "chrome/browser/chromeos/cros/network_library.h"
9 #include "chrome/browser/chromeos/login/background_view.h"
10 #include "chrome/browser/chromeos/login/login_utils.h"
11 #include "chrome/browser/chromeos/options/network_config_view.h"
12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/browser/ui/browser_list.h"
14 #include "chrome/browser/ui/browser_window.h"
15 #include "chrome/browser/ui/views/window.h"
16 #include "views/window/dialog_delegate.h"
17 #include "views/window/window.h"
18
19 namespace chromeos {
20
NetworkLoginObserver(NetworkLibrary * netlib)21 NetworkLoginObserver::NetworkLoginObserver(NetworkLibrary* netlib) {
22 RefreshStoredNetworks(netlib->wifi_networks(),
23 netlib->virtual_networks());
24 netlib->AddNetworkManagerObserver(this);
25 }
26
~NetworkLoginObserver()27 NetworkLoginObserver::~NetworkLoginObserver() {
28 CrosLibrary::Get()->GetNetworkLibrary()->RemoveNetworkManagerObserver(this);
29 }
30
CreateModalPopup(views::WindowDelegate * view)31 void NetworkLoginObserver::CreateModalPopup(views::WindowDelegate* view) {
32 Browser* browser = BrowserList::GetLastActive();
33 if (browser && browser->type() != Browser::TYPE_NORMAL) {
34 browser = BrowserList::FindBrowserWithType(browser->profile(),
35 Browser::TYPE_NORMAL,
36 true);
37 }
38 if (browser) {
39 views::Window* window = browser::CreateViewsWindow(
40 browser->window()->GetNativeHandle(), gfx::Rect(), view);
41 window->SetIsAlwaysOnTop(true);
42 window->Show();
43 } else {
44 // Browser not found, so we should be in login/oobe screen.
45 BackgroundView* background_view = LoginUtils::Get()->GetBackgroundView();
46 if (background_view) {
47 background_view->CreateModalPopup(view);
48 }
49 }
50 }
51
RefreshStoredNetworks(const WifiNetworkVector & wifi_networks,const VirtualNetworkVector & virtual_networks)52 void NetworkLoginObserver::RefreshStoredNetworks(
53 const WifiNetworkVector& wifi_networks,
54 const VirtualNetworkVector& virtual_networks) {
55 network_failures_.clear();
56 for (WifiNetworkVector::const_iterator it = wifi_networks.begin();
57 it != wifi_networks.end(); it++) {
58 const WifiNetwork* wifi = *it;
59 network_failures_[wifi->service_path()] = wifi->failed();
60 }
61 for (VirtualNetworkVector::const_iterator it = virtual_networks.begin();
62 it != virtual_networks.end(); it++) {
63 const VirtualNetwork* vpn = *it;
64 network_failures_[vpn->service_path()] = vpn->failed();
65 }
66 }
67
OnNetworkManagerChanged(NetworkLibrary * cros)68 void NetworkLoginObserver::OnNetworkManagerChanged(NetworkLibrary* cros) {
69 const WifiNetworkVector& wifi_networks = cros->wifi_networks();
70 const VirtualNetworkVector& virtual_networks = cros->virtual_networks();
71
72 NetworkConfigView* view = NULL;
73 // Check to see if we have any newly failed wifi network.
74 for (WifiNetworkVector::const_iterator it = wifi_networks.begin();
75 it != wifi_networks.end(); it++) {
76 WifiNetwork* wifi = *it;
77 if (wifi->failed()) {
78 NetworkFailureMap::iterator iter =
79 network_failures_.find(wifi->service_path());
80 // If the network did not previously exist, then don't do anything.
81 // For example, if the user travels to a location and finds a service
82 // that has previously failed, we don't want to show an error.
83 if (iter == network_failures_.end())
84 continue;
85
86 // If this network was in a failed state previously, then it's not new.
87 if (iter->second)
88 continue;
89
90 // Display login dialog again for bad_passphrase and bad_wepkey errors.
91 // Always re-display the login dialog for added networks that failed to
92 // connect for any reason (e.g. incorrect security type was chosen).
93 if (wifi->error() == ERROR_BAD_PASSPHRASE ||
94 wifi->error() == ERROR_BAD_WEPKEY ||
95 wifi->added()) {
96 // The NetworkConfigView will show the appropriate error message.
97 view = new NetworkConfigView(wifi);
98 // There should only be one wifi network that failed to connect.
99 // If for some reason, we have more than one failure,
100 // we only display the first one. So we break here.
101 break;
102 }
103 }
104 }
105 // Check to see if we have any newly failed virtual network.
106 // See wifi section for detailed comments.
107 if (!view) {
108 for (VirtualNetworkVector::const_iterator it = virtual_networks.begin();
109 it != virtual_networks.end(); it++) {
110 VirtualNetwork* vpn = *it;
111 if (vpn->failed()) {
112 NetworkFailureMap::iterator iter =
113 network_failures_.find(vpn->service_path());
114 if (iter == network_failures_.end())
115 continue; // New network.
116 if (iter->second)
117 continue; // Previous failure.
118 if (vpn->error() == ERROR_BAD_PASSPHRASE || vpn->added()) {
119 view = new NetworkConfigView(vpn);
120 break;
121 }
122 }
123 }
124 }
125
126 RefreshStoredNetworks(wifi_networks, virtual_networks);
127
128 // Show login box if necessary.
129 if (view)
130 CreateModalPopup(view);
131 }
132
133 } // namespace chromeos
134