network_message_observer.cc revision 731df977c0511bca2206b5f333555b1205ff1f43
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/callback.h" 9#include "base/string_number_conversions.h" 10#include "base/utf_string_conversions.h" 11#include "chrome/browser/browser.h" 12#include "chrome/browser/browser_list.h" 13#include "chrome/browser/browser_window.h" 14#include "chrome/browser/chromeos/cros/cros_library.h" 15#include "chrome/browser/chromeos/cros/network_library.h" 16#include "chrome/browser/chromeos/notifications/balloon_view_host.h" 17#include "chrome/browser/chromeos/options/network_config_view.h" 18#include "chrome/browser/views/window.h" 19#include "grit/generated_resources.h" 20#include "grit/theme_resources.h" 21#include "views/window/dialog_delegate.h" 22#include "views/window/window.h" 23 24namespace chromeos { 25 26NetworkMessageObserver::NetworkMessageObserver(Profile* profile) 27 : initialized_(false), 28 notification_connection_error_(profile, "network_connection.chromeos", 29 IDR_NOTIFICATION_NETWORK_FAILED, 30 l10n_util::GetStringUTF16(IDS_NETWORK_CONNECTION_ERROR_TITLE)), 31 notification_low_data_(profile, "network_low_data.chromeos", 32 IDR_NOTIFICATION_BARS_CRITICAL, 33 l10n_util::GetStringUTF16(IDS_NETWORK_LOW_DATA_TITLE)), 34 notification_no_data_(profile, "network_no_data.chromeos", 35 IDR_NOTIFICATION_BARS_EMPTY, 36 l10n_util::GetStringUTF16(IDS_NETWORK_OUT_OF_DATA_TITLE)) { 37 NetworkChanged(CrosLibrary::Get()->GetNetworkLibrary()); 38 initialized_ = true; 39} 40 41NetworkMessageObserver::~NetworkMessageObserver() { 42 notification_connection_error_.Hide(); 43 notification_low_data_.Hide(); 44 notification_no_data_.Hide(); 45} 46 47void NetworkMessageObserver::CreateModalPopup(views::WindowDelegate* view) { 48 Browser* browser = BrowserList::GetLastActive(); 49 if (browser && browser->type() != Browser::TYPE_NORMAL) { 50 browser = BrowserList::FindBrowserWithType(browser->profile(), 51 Browser::TYPE_NORMAL, 52 true); 53 } 54 DCHECK(browser); 55 views::Window* window = browser::CreateViewsWindow( 56 browser->window()->GetNativeHandle(), gfx::Rect(), view); 57 window->SetIsAlwaysOnTop(true); 58 window->Show(); 59} 60 61void NetworkMessageObserver::MobileSetup(const ListValue* args) { 62 BrowserList::GetLastActive()->OpenMobilePlanTabAndActivate(); 63} 64 65void NetworkMessageObserver::NetworkChanged(NetworkLibrary* obj) { 66 const WifiNetworkVector& wifi_networks = obj->wifi_networks(); 67 const CellularNetworkVector& cellular_networks = obj->cellular_networks(); 68 69 NetworkConfigView* view = NULL; 70 std::string new_failed_network; 71 // Check to see if we have any newly failed wifi network. 72 for (WifiNetworkVector::const_iterator it = wifi_networks.begin(); 73 it < wifi_networks.end(); it++) { 74 const WifiNetwork& wifi = *it; 75 if (wifi.failed()) { 76 ServicePathWifiMap::iterator iter = 77 wifi_networks_.find(wifi.service_path()); 78 // If the network did not previously exist, then don't do anything. 79 // For example, if the user travels to a location and finds a service 80 // that has previously failed, we don't want to show a notification. 81 if (iter == wifi_networks_.end()) 82 continue; 83 84 const WifiNetwork& wifi_old = iter->second; 85 // If this network was in a failed state previously, then it's not new. 86 if (wifi_old.failed()) 87 continue; 88 89 // Display login box again for bad_passphrase and bad_wepkey errors. 90 if (wifi.error() == ERROR_BAD_PASSPHRASE || 91 wifi.error() == ERROR_BAD_WEPKEY) { 92 // The NetworkConfigView will show the appropriate error message. 93 view = new NetworkConfigView(wifi, true); 94 // There should only be one wifi network that failed to connect. 95 // If for some reason, we have more than one failure, 96 // we only display the first one. So we break here. 97 break; 98 } 99 100 // If network connection failed, display a notification. 101 // We only do this if we were trying to make a new connection. 102 // So if a previously connected network got disconnected for any reason, 103 // we don't display notification. 104 if (wifi_old.connecting()) { 105 new_failed_network = wifi.name(); 106 // Like above, there should only be one newly failed network. 107 break; 108 } 109 } 110 111 // If we find any network connecting, we hide the error notification. 112 if (wifi.connecting()) { 113 notification_connection_error_.Hide(); 114 } 115 } 116 117 // Refresh stored networks. 118 wifi_networks_.clear(); 119 for (WifiNetworkVector::const_iterator it = wifi_networks.begin(); 120 it < wifi_networks.end(); it++) { 121 const WifiNetwork& wifi = *it; 122 wifi_networks_[wifi.service_path()] = wifi; 123 } 124 cellular_networks_.clear(); 125 for (CellularNetworkVector::const_iterator it = cellular_networks.begin(); 126 it < cellular_networks.end(); it++) { 127 const CellularNetwork& cellular = *it; 128 cellular_networks_[cellular.service_path()] = cellular; 129 } 130 131 // Show connection error notification if necessary. 132 if (!new_failed_network.empty()) { 133 // Hide if already shown to force show it in case user has closed it. 134 if (notification_connection_error_.visible()) 135 notification_connection_error_.Hide(); 136 notification_connection_error_.Show(l10n_util::GetStringFUTF16( 137 IDS_NETWORK_CONNECTION_ERROR_MESSAGE, 138 ASCIIToUTF16(new_failed_network)), false, false); 139 } 140 141 // Show login box if necessary. 142 if (view && initialized_) 143 CreateModalPopup(view); 144} 145 146void NetworkMessageObserver::CellularDataPlanChanged(NetworkLibrary* obj) { 147 const CellularNetwork& cellular = obj->cellular_network(); 148 // Active plan is the first one in the list. Use empty one if none found. 149 const CellularDataPlanList& plans = cellular.GetDataPlans(); 150 CellularDataPlan plan = plans.empty() ? CellularDataPlan() : plans[0]; 151 // If connected cellular network changed, or data plan is different, then 152 // it's a new network. Then hide all previous notifications. 153 bool new_plan = false; 154 if (cellular.service_path() != cellular_service_path_) { 155 cellular_service_path_ = cellular.service_path(); 156 new_plan = true; 157 } else if (plan.plan_name != cellular_data_plan_.plan_name || 158 plan.plan_type != cellular_data_plan_.plan_type) { 159 new_plan = true; 160 } 161 if (new_plan) { 162 // New network, so hide the notifications and set the notifications title. 163 notification_low_data_.Hide(); 164 notification_no_data_.Hide(); 165 if (plan.plan_type == CELLULAR_DATA_PLAN_UNLIMITED) { 166 notification_no_data_.set_title( 167 l10n_util::GetStringFUTF16(IDS_NETWORK_DATA_EXPIRED_TITLE, 168 ASCIIToUTF16(plan.plan_name))); 169 notification_low_data_.set_title( 170 l10n_util::GetStringFUTF16(IDS_NETWORK_NEARING_EXPIRATION_TITLE, 171 ASCIIToUTF16(plan.plan_name))); 172 } else { 173 notification_no_data_.set_title( 174 l10n_util::GetStringFUTF16(IDS_NETWORK_OUT_OF_DATA_TITLE, 175 ASCIIToUTF16(plan.plan_name))); 176 notification_low_data_.set_title( 177 l10n_util::GetStringFUTF16(IDS_NETWORK_LOW_DATA_TITLE, 178 ASCIIToUTF16(plan.plan_name))); 179 } 180 } 181 182 if (plan.plan_type != CELLULAR_DATA_PLAN_UNKNOWN) { 183 if (cellular.data_left() == CellularNetwork::DATA_NONE) { 184 notification_low_data_.Hide(); 185 int message = plan.plan_type == CELLULAR_DATA_PLAN_UNLIMITED ? 186 IDS_NETWORK_MINUTES_REMAINING_MESSAGE : 187 IDS_NETWORK_DATA_REMAINING_MESSAGE; 188 notification_no_data_.Show(l10n_util::GetStringFUTF16( 189 message, ASCIIToUTF16("0")), 190 l10n_util::GetStringUTF16(IDS_NETWORK_PURCHASE_MORE_MESSAGE), 191 NewCallback(this, &NetworkMessageObserver::MobileSetup), 192 false, false); 193 } else if (cellular.data_left() == CellularNetwork::DATA_VERY_LOW) { 194 notification_no_data_.Hide(); 195 int message = plan.plan_type == CELLULAR_DATA_PLAN_UNLIMITED ? 196 IDS_NETWORK_MINUTES_REMAINING_MESSAGE : 197 IDS_NETWORK_DATA_REMAINING_MESSAGE; 198 int64 remaining = plan.plan_type == CELLULAR_DATA_PLAN_UNLIMITED ? 199 (plan.plan_end_time - plan.update_time) / 60 : 200 (plan.plan_data_bytes - plan.data_bytes_used) / (1024 * 1024); 201 notification_low_data_.Show(l10n_util::GetStringFUTF16( 202 message, UTF8ToUTF16(base::Int64ToString(remaining))), 203 l10n_util::GetStringUTF16(IDS_NETWORK_PURCHASE_MORE_MESSAGE), 204 NewCallback(this, &NetworkMessageObserver::MobileSetup), 205 false, false); 206 } else { 207 // Got data, so hide notifications. 208 notification_low_data_.Hide(); 209 notification_no_data_.Hide(); 210 } 211 } 212 213 cellular_data_plan_ = plan; 214} 215 216} // namespace chromeos 217