172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/network_message_observer.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/callback.h" 8513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/stl_util-inl.h" 9731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/string_number_conversions.h" 103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/cros/cros_library.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/cros/network_library.h" 13731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/chromeos/notifications/balloon_view_host.h" 14201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/browser/prefs/pref_service.h" 1521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h" 164a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser.h" 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_list.h" 18201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/common/pref_names.h" 19201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/common/time_format.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/theme_resources.h" 2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h" 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 24201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochnamespace { 25201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 26201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Returns prefs::kShowPlanNotifications in the profile of the last active 27201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// browser. If there is no active browser, returns true. 28201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochbool ShouldShowMobilePlanNotifications() { 29201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch Browser* browser = BrowserList::GetLastActive(); 30201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (!browser || !browser->profile()) 31201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return true; 32201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 33201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch PrefService* prefs = browser->profile()->GetPrefs(); 34201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return prefs->GetBoolean(prefs::kShowPlanNotifications); 35201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 36201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 37201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} // namespace 38201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace chromeos { 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNetworkMessageObserver::NetworkMessageObserver(Profile* profile) 4272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen : notification_connection_error_(profile, "network_connection.chromeos", 43731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick IDR_NOTIFICATION_NETWORK_FAILED, 44731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick l10n_util::GetStringUTF16(IDS_NETWORK_CONNECTION_ERROR_TITLE)), 45731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick notification_low_data_(profile, "network_low_data.chromeos", 46731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick IDR_NOTIFICATION_BARS_CRITICAL, 47731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick l10n_util::GetStringUTF16(IDS_NETWORK_LOW_DATA_TITLE)), 48731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick notification_no_data_(profile, "network_no_data.chromeos", 49731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick IDR_NOTIFICATION_BARS_EMPTY, 50731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick l10n_util::GetStringUTF16(IDS_NETWORK_OUT_OF_DATA_TITLE)) { 51513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NetworkLibrary* netlib = CrosLibrary::Get()->GetNetworkLibrary(); 52513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch OnNetworkManagerChanged(netlib); 53dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Note that this gets added as a NetworkManagerObserver, 54dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // CellularDataPlanObserver, and UserActionObserver in browser_init.cc 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNetworkMessageObserver::~NetworkMessageObserver() { 58513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch NetworkLibrary* netlib = CrosLibrary::Get()->GetNetworkLibrary(); 59513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch netlib->RemoveNetworkManagerObserver(this); 60513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch netlib->RemoveCellularDataPlanObserver(this); 61dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen netlib->RemoveUserActionObserver(this); 62731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick notification_connection_error_.Hide(); 63731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick notification_low_data_.Hide(); 64731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick notification_no_data_.Hide(); 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// static 6872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool NetworkMessageObserver::IsApplicableBackupPlan( 6972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const CellularDataPlan* plan, const CellularDataPlan* other_plan) { 7072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // By applicable plan, we mean that the other plan has data AND the timeframe 7172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // will apply: (unlimited OR used bytes < max bytes) AND 7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // ((start time - 1 sec) <= end time of currently active plan). 7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // In other words, there is data available and there is no gap of more than a 7472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // second in time between the old plan and the new plan. 7572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen bool has_data = other_plan->plan_type == CELLULAR_DATA_PLAN_UNLIMITED || 7672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen other_plan->remaining_data() > 0; 7772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen bool will_apply = 7872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen (other_plan->plan_start_time - plan->plan_end_time).InSeconds() <= 1; 7972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return has_data && will_apply; 803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 824a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochvoid NetworkMessageObserver::OpenMobileSetupPage(const ListValue* args) { 834a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch Browser* browser = BrowserList::GetLastActive(); 844a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (browser) 854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch browser->OpenMobilePlanTabAndActivate(); 864a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch} 874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 884a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochvoid NetworkMessageObserver::OpenMoreInfoPage(const ListValue* args) { 894a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch Browser* browser = BrowserList::GetLastActive(); 904a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (!browser) 914a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return; 924a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch chromeos::NetworkLibrary* lib = 934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch chromeos::CrosLibrary::Get()->GetNetworkLibrary(); 9421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const chromeos::CellularNetwork* cellular = lib->cellular_network(); 954a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (!cellular) 964a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return; 97dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen browser->ShowSingletonTab(GURL(cellular->payment_url())); 98731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 99731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 100dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid NetworkMessageObserver::InitNewPlan(const CellularDataPlan* plan) { 10172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen notification_low_data_.Hide(); 10272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen notification_no_data_.Hide(); 10372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (plan->plan_type == CELLULAR_DATA_PLAN_UNLIMITED) { 10472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen notification_no_data_.set_title( 10572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen l10n_util::GetStringFUTF16(IDS_NETWORK_DATA_EXPIRED_TITLE, 10672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASCIIToUTF16(plan->plan_name))); 10772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen notification_low_data_.set_title( 10872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen l10n_util::GetStringFUTF16(IDS_NETWORK_NEARING_EXPIRATION_TITLE, 10972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASCIIToUTF16(plan->plan_name))); 11072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else { 11172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen notification_no_data_.set_title( 11272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen l10n_util::GetStringFUTF16(IDS_NETWORK_OUT_OF_DATA_TITLE, 11372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASCIIToUTF16(plan->plan_name))); 11472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen notification_low_data_.set_title( 11572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen l10n_util::GetStringFUTF16(IDS_NETWORK_LOW_DATA_TITLE, 11672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ASCIIToUTF16(plan->plan_name))); 11772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 11872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 11972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 120dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid NetworkMessageObserver::ShowNeedsPlanNotification( 121dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const CellularNetwork* cellular) { 122dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen notification_no_data_.set_title( 123dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen l10n_util::GetStringFUTF16(IDS_NETWORK_NO_DATA_PLAN_TITLE, 124dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen UTF8ToUTF16(cellular->name()))); 125dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen notification_no_data_.Show( 126dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen l10n_util::GetStringFUTF16( 127dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen IDS_NETWORK_NO_DATA_PLAN_MESSAGE, 128dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen UTF8ToUTF16(cellular->name())), 129dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen l10n_util::GetStringUTF16(IDS_NETWORK_PURCHASE_MORE_MESSAGE), 130dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NewCallback(this, &NetworkMessageObserver::OpenMobileSetupPage), 131dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen false, false); 132dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 133dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 13472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid NetworkMessageObserver::ShowNoDataNotification( 135dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CellularDataPlanType plan_type) { 136dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen notification_low_data_.Hide(); // Hide previous low data notification. 137dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen string16 message = plan_type == CELLULAR_DATA_PLAN_UNLIMITED ? 138dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen TimeFormat::TimeRemaining(base::TimeDelta()) : 139dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen l10n_util::GetStringFUTF16(IDS_NETWORK_DATA_REMAINING_MESSAGE, 140dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ASCIIToUTF16("0")); 14172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen notification_no_data_.Show(message, 14272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen l10n_util::GetStringUTF16(IDS_NETWORK_PURCHASE_MORE_MESSAGE), 14372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NewCallback(this, &NetworkMessageObserver::OpenMobileSetupPage), 14472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen false, false); 14572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 14672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 14772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid NetworkMessageObserver::ShowLowDataNotification( 14872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const CellularDataPlan* plan) { 149dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen string16 message; 150dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (plan->plan_type == CELLULAR_DATA_PLAN_UNLIMITED) { 151dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen message = plan->GetPlanExpiration(); 152dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else { 153dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int64 remaining_mbytes = plan->remaining_data() / (1024 * 1024); 154dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen message = l10n_util::GetStringFUTF16(IDS_NETWORK_DATA_REMAINING_MESSAGE, 155dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen UTF8ToUTF16(base::Int64ToString(remaining_mbytes))); 156dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 15772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen notification_low_data_.Show(message, 15872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen l10n_util::GetStringUTF16(IDS_NETWORK_MORE_INFO_MESSAGE), 15972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NewCallback(this, &NetworkMessageObserver::OpenMoreInfoPage), 16072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen false, false); 16172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 16272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool NetworkMessageObserver::CheckNetworkFailed(const Network* network) { 164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (network->failed()) { 165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NetworkStateMap::iterator iter = 166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen network_states_.find(network->service_path()); 167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If the network did not previously exist, then don't do anything. 168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // For example, if the user travels to a location and finds a service 169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // that has previously failed, we don't want to show a notification. 170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (iter == network_states_.end()) 171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If network connection failed, display a notification. 173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // We only do this if we were trying to make a new connection. 174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // So if a previously connected network got disconnected for any reason, 175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // we don't display notification. 176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ConnectionState prev_state = iter->second; 177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (Network::IsConnectingState(prev_state)) 178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid NetworkMessageObserver::OnNetworkManagerChanged(NetworkLibrary* cros) { 184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const Network* new_failed_network = NULL; 185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Check to see if we have any newly failed networks. 186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (WifiNetworkVector::const_iterator it = cros->wifi_networks().begin(); 187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen it != cros->wifi_networks().end(); it++) { 188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const WifiNetwork* net = *it; 189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (CheckNetworkFailed(net)) { 190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new_failed_network = net; 191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen break; // There should only be one failed network. 1923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!new_failed_network) { 196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (CellularNetworkVector::const_iterator it = 197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen cros->cellular_networks().begin(); 198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen it != cros->cellular_networks().end(); it++) { 199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const CellularNetwork* net = *it; 200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (CheckNetworkFailed(net)) { 201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new_failed_network = net; 202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen break; // There should only be one failed network. 203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 2053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 206513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!new_failed_network) { 208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (VirtualNetworkVector::const_iterator it = 209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen cros->virtual_networks().begin(); 210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen it != cros->virtual_networks().end(); it++) { 211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const VirtualNetwork* net = *it; 212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (CheckNetworkFailed(net)) { 213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new_failed_network = net; 214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen break; // There should only be one failed network. 215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 2173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen network_states_.clear(); 220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (WifiNetworkVector::const_iterator it = cros->wifi_networks().begin(); 221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen it != cros->wifi_networks().end(); it++) 222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen network_states_[(*it)->service_path()] = (*it)->state(); 223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (CellularNetworkVector::const_iterator it = 224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen cros->cellular_networks().begin(); 225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen it != cros->cellular_networks().end(); it++) 226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen network_states_[(*it)->service_path()] = (*it)->state(); 227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (VirtualNetworkVector::const_iterator it = 228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen cros->virtual_networks().begin(); 229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen it != cros->virtual_networks().end(); it++) 230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen network_states_[(*it)->service_path()] = (*it)->state(); 231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 232731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Show connection error notification if necessary. 233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (new_failed_network) { 2343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Hide if already shown to force show it in case user has closed it. 235731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (notification_connection_error_.visible()) 236731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick notification_connection_error_.Hide(); 237731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick notification_connection_error_.Show(l10n_util::GetStringFUTF16( 2383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick IDS_NETWORK_CONNECTION_ERROR_MESSAGE, 239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UTF8ToUTF16(new_failed_network->name())), false, false); 2403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 243dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid NetworkMessageObserver::OnCellularDataPlanChanged(NetworkLibrary* cros) { 244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!ShouldShowMobilePlanNotifications()) 245513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return; 246dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const CellularNetwork* cellular = cros->cellular_network(); 247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!cellular || !cellular->SupportsDataPlan()) 248201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return; 249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 250dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const CellularDataPlanVector* plans = 251dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen cros->GetDataPlans(cellular->service_path()); 25272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // If no plans available, check to see if we need a new plan. 253dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!plans || plans->empty()) { 254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If previously, we had low data, we know that a plan was near expiring. 255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // In that case, because the plan disappeared, we assume that it expired. 256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (cellular_data_left_ == CellularNetwork::DATA_LOW) { 257dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ShowNoDataNotification(cellular_data_plan_type_); 258dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else if (cellular->needs_new_plan()) { 259dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ShowNeedsPlanNotification(cellular); 26072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SaveLastCellularInfo(cellular, NULL); 26272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return; 26372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 26472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 265dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen CellularDataPlanVector::const_iterator iter = plans->begin(); 26672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const CellularDataPlan* current_plan = *iter; 26772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 26872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // If current plan is not the last plan (there is another backup plan), 26972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // then we do not show notifications for this plan. 27072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // For example, if there is another data plan available when this runs out. 271dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen for (++iter; iter != plans->end(); ++iter) { 27272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (IsApplicableBackupPlan(current_plan, *iter)) { 273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SaveLastCellularInfo(cellular, current_plan); 2744a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return; 275731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 276731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 277731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 27872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // If connected cellular network changed, or data plan is different, then 27972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // it's a new network. Then hide all previous notifications. 28072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen bool new_plan = cellular->service_path() != cellular_service_path_ || 28172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen current_plan->GetUniqueIdentifier() != cellular_data_plan_unique_id_; 28272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 28372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (new_plan) { 28472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen InitNewPlan(current_plan); 28572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 286731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 287dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (cellular->data_left() == CellularNetwork::DATA_NONE) { 288dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ShowNoDataNotification(current_plan->plan_type); 289dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else if (cellular->data_left() == CellularNetwork::DATA_VERY_LOW) { 290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Only show low data notification if we transition to very low data 291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // and we are on the same plan. This is so that users don't get a 292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // notification whenever they connect to a low data 3g network. 293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!new_plan && (cellular_data_left_ != CellularNetwork::DATA_VERY_LOW)) 294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ShowLowDataNotification(current_plan); 2954a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 29672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SaveLastCellularInfo(cellular, current_plan); 298dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 299dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid NetworkMessageObserver::OnConnectionInitiated(NetworkLibrary* cros, 301dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const Network* network) { 302dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // If user initiated any network connection, we hide the error notification. 303dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen notification_connection_error_.Hide(); 304731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 305731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid NetworkMessageObserver::SaveLastCellularInfo( 307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const CellularNetwork* cellular, const CellularDataPlan* plan) { 308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(cellular); 309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen cellular_service_path_ = cellular->service_path(); 310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen cellular_data_left_ = cellular->data_left(); 311ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (plan) { 312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen cellular_data_plan_unique_id_ = plan->GetUniqueIdentifier(); 313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen cellular_data_plan_type_ = plan->plan_type; 314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen cellular_data_plan_unique_id_ = std::string(); 316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen cellular_data_plan_type_ = CELLULAR_DATA_PLAN_UNKNOWN; 317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace chromeos 321