network_message_observer.cc revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
1// Copyright (c) 2010 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_message_observer.h"
6
7#include "app/l10n_util.h"
8#include "base/utf_string_conversions.h"
9#include "chrome/browser/browser_list.h"
10#include "chrome/browser/browser_window.h"
11#include "chrome/browser/chromeos/cros/cros_library.h"
12#include "chrome/browser/chromeos/cros/network_library.h"
13#include "chrome/browser/chromeos/options/network_config_view.h"
14#include "grit/generated_resources.h"
15#include "grit/theme_resources.h"
16#include "views/window/dialog_delegate.h"
17#include "views/window/window.h"
18
19namespace chromeos {
20
21NetworkMessageObserver::NetworkMessageObserver(Profile* profile)
22    : initialized_(false),
23      notification_(profile, "network_connection.chromeos",
24        IDR_NOTIFICATION_NETWORK_FAILED,
25        l10n_util::GetStringUTF16(IDS_NETWORK_CONNECTION_ERROR_TITLE)) {
26  NetworkChanged(CrosLibrary::Get()->GetNetworkLibrary());
27  initialized_ = true;
28}
29
30NetworkMessageObserver::~NetworkMessageObserver() {
31  notification_.Hide();
32}
33
34void NetworkMessageObserver::CreateModalPopup(views::WindowDelegate* view) {
35  Browser* browser = BrowserList::GetLastActive();
36  if (browser && browser->type() != Browser::TYPE_NORMAL) {
37    browser = BrowserList::FindBrowserWithType(browser->profile(),
38                                               Browser::TYPE_NORMAL,
39                                               true);
40  }
41  DCHECK(browser);
42  views::Window* window = views::Window::CreateChromeWindow(
43      browser->window()->GetNativeHandle(), gfx::Rect(), view);
44  window->SetIsAlwaysOnTop(true);
45  window->Show();
46}
47
48void NetworkMessageObserver::NetworkChanged(NetworkLibrary* obj) {
49  const WifiNetworkVector& wifi_networks = obj->wifi_networks();
50  const CellularNetworkVector& cellular_networks = obj->cellular_networks();
51
52  NetworkConfigView* view = NULL;
53  std::string new_failed_network;
54  // Check to see if we have any newly failed wifi network.
55  for (WifiNetworkVector::const_iterator it = wifi_networks.begin();
56       it < wifi_networks.end(); it++) {
57    const WifiNetwork& wifi = *it;
58    if (wifi.failed()) {
59      ServicePathWifiMap::iterator iter =
60          wifi_networks_.find(wifi.service_path());
61      // If the network did not previously exist, then don't do anything.
62      // For example, if the user travels to a location and finds a service
63      // that has previously failed, we don't want to show a notification.
64      if (iter == wifi_networks_.end())
65        continue;
66
67      const WifiNetwork& wifi_old = iter->second;
68      // If this network was in a failed state previously, then it's not new.
69      if (wifi_old.failed())
70        continue;
71
72      // Display login box again for bad_passphrase and bad_wepkey errors.
73      if (wifi.error() == ERROR_BAD_PASSPHRASE ||
74          wifi.error() == ERROR_BAD_WEPKEY) {
75        // The NetworkConfigView will show the appropriate error message.
76        view = new NetworkConfigView(wifi, true);
77        // There should only be one wifi network that failed to connect.
78        // If for some reason, we have more than one failure,
79        // we only display the first one. So we break here.
80        break;
81      }
82
83      // If network connection failed, display a notification.
84      // We only do this if we were trying to make a new connection.
85      // So if a previously connected network got disconnected for any reason,
86      // we don't display notification.
87      if (wifi_old.connecting()) {
88        new_failed_network = wifi.name();
89        // Like above, there should only be one newly failed network.
90        break;
91      }
92    }
93
94    // If we find any network connecting, we hide any notifications.
95    if (wifi.connecting()) {
96      notification_.Hide();
97    }
98  }
99
100  // Refresh stored networks.
101  wifi_networks_.clear();
102  for (WifiNetworkVector::const_iterator it = wifi_networks.begin();
103       it < wifi_networks.end(); it++) {
104    const WifiNetwork& wifi = *it;
105    wifi_networks_[wifi.service_path()] = wifi;
106  }
107  cellular_networks_.clear();
108  for (CellularNetworkVector::const_iterator it = cellular_networks.begin();
109       it < cellular_networks.end(); it++) {
110    const CellularNetwork& cellular = *it;
111    cellular_networks_[cellular.service_path()] = cellular;
112  }
113
114  // Show notification if necessary.
115  if (!new_failed_network.empty()) {
116    // Hide if already shown to force show it in case user has closed it.
117    if (notification_.visible())
118      notification_.Hide();
119    notification_.Show(l10n_util::GetStringFUTF16(
120        IDS_NETWORK_CONNECTION_ERROR_MESSAGE,
121        ASCIIToUTF16(new_failed_network)), false, true);
122  }
123
124  // Show login box if necessary.
125  if (view && initialized_)
126    CreateModalPopup(view);
127}
128
129}  // namespace chromeos
130