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/status/data_promo_notification.h" 6 7 #include "ash/shell.h" 8 #include "ash/shell_window_ids.h" 9 #include "ash/system/chromeos/network/network_observer.h" 10 #include "ash/system/tray/system_tray.h" 11 #include "ash/system/tray/system_tray_notifier.h" 12 #include "base/prefs/pref_registry_simple.h" 13 #include "base/prefs/pref_service.h" 14 #include "base/strings/utf_string_conversions.h" 15 #include "chrome/browser/browser_process.h" 16 #include "chrome/browser/chromeos/cros/network_library.h" 17 #include "chrome/browser/chromeos/login/helper.h" 18 #include "chrome/browser/chromeos/mobile_config.h" 19 #include "chrome/browser/profiles/profile.h" 20 #include "chrome/browser/profiles/profile_manager.h" 21 #include "chrome/browser/ui/browser.h" 22 #include "chrome/browser/ui/browser_list.h" 23 #include "chrome/common/pref_names.h" 24 #include "chromeos/login/login_state.h" 25 #include "grit/generated_resources.h" 26 #include "grit/theme_resources.h" 27 #include "ui/base/l10n/l10n_util.h" 28 #include "ui/base/resource/resource_bundle.h" 29 #include "ui/views/view.h" 30 #include "ui/views/widget/widget.h" 31 32 namespace { 33 34 // Time in milliseconds to delay showing of promo 35 // notification when Chrome window is not on screen. 36 const int kPromoShowDelayMs = 10000; 37 38 const int kNotificationCountPrefDefault = -1; 39 40 bool GetBooleanPref(const char* pref_name) { 41 Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord(); 42 PrefService* prefs = profile->GetPrefs(); 43 return prefs->GetBoolean(pref_name); 44 } 45 46 int GetIntegerLocalPref(const char* pref_name) { 47 PrefService* prefs = g_browser_process->local_state(); 48 return prefs->GetInteger(pref_name); 49 } 50 51 void SetBooleanPref(const char* pref_name, bool value) { 52 Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord(); 53 PrefService* prefs = profile->GetPrefs(); 54 prefs->SetBoolean(pref_name, value); 55 } 56 57 void SetIntegerLocalPref(const char* pref_name, int value) { 58 PrefService* prefs = g_browser_process->local_state(); 59 prefs->SetInteger(pref_name, value); 60 } 61 62 // Returns prefs::kShow3gPromoNotification or false 63 // if there's no active browser. 64 bool ShouldShow3gPromoNotification() { 65 return GetBooleanPref(prefs::kShow3gPromoNotification); 66 } 67 68 void SetShow3gPromoNotification(bool value) { 69 SetBooleanPref(prefs::kShow3gPromoNotification, value); 70 } 71 72 // Returns prefs::kCarrierDealPromoShown which is number of times 73 // carrier deal notification has been shown to users on this machine. 74 int GetCarrierDealPromoShown() { 75 return GetIntegerLocalPref(prefs::kCarrierDealPromoShown); 76 } 77 78 void SetCarrierDealPromoShown(int value) { 79 SetIntegerLocalPref(prefs::kCarrierDealPromoShown, value); 80 } 81 82 const chromeos::MobileConfig::Carrier* GetCarrier( 83 chromeos::NetworkLibrary* cros) { 84 std::string carrier_id = cros->GetCellularHomeCarrierId(); 85 if (carrier_id.empty()) { 86 LOG(ERROR) << "Empty carrier ID with a cellular connected."; 87 return NULL; 88 } 89 90 chromeos::MobileConfig* config = chromeos::MobileConfig::GetInstance(); 91 if (!config->IsReady()) 92 return NULL; 93 94 return config->GetCarrier(carrier_id); 95 } 96 97 const chromeos::MobileConfig::CarrierDeal* GetCarrierDeal( 98 const chromeos::MobileConfig::Carrier* carrier) { 99 const chromeos::MobileConfig::CarrierDeal* deal = carrier->GetDefaultDeal(); 100 if (deal) { 101 // Check deal for validity. 102 int carrier_deal_promo_pref = GetCarrierDealPromoShown(); 103 if (carrier_deal_promo_pref >= deal->notification_count()) 104 return NULL; 105 const std::string locale = g_browser_process->GetApplicationLocale(); 106 std::string deal_text = deal->GetLocalizedString(locale, 107 "notification_text"); 108 if (deal_text.empty()) 109 return NULL; 110 } 111 return deal; 112 } 113 114 } // namespace 115 116 namespace chromeos { 117 118 //////////////////////////////////////////////////////////////////////////////// 119 // DataPromoNotification 120 121 DataPromoNotification::DataPromoNotification() 122 : check_for_promo_(true), 123 weak_ptr_factory_(this) { 124 } 125 126 DataPromoNotification::~DataPromoNotification() { 127 CloseNotification(); 128 } 129 130 void DataPromoNotification::RegisterPrefs(PrefRegistrySimple* registry) { 131 // Carrier deal notification shown count defaults to 0. 132 registry->RegisterIntegerPref(prefs::kCarrierDealPromoShown, 0); 133 } 134 135 void DataPromoNotification::ShowOptionalMobileDataPromoNotification( 136 NetworkLibrary* cros, 137 views::View* host, 138 ash::NetworkTrayDelegate* listener) { 139 // Display one-time notification for regular users on first use 140 // of Mobile Data connection or if there's a carrier deal defined 141 // show that even if user has already seen generic promo. 142 if (LoginState::Get()->IsUserAuthenticated() && 143 check_for_promo_ && 144 cros->cellular_connected() && !cros->ethernet_connected() && 145 !cros->wifi_connected() && !cros->wimax_connected()) { 146 std::string deal_text; 147 int carrier_deal_promo_pref = kNotificationCountPrefDefault; 148 const MobileConfig::CarrierDeal* deal = NULL; 149 const MobileConfig::Carrier* carrier = GetCarrier(cros); 150 if (carrier) 151 deal = GetCarrierDeal(carrier); 152 deal_info_url_.clear(); 153 deal_topup_url_.clear(); 154 if (deal) { 155 carrier_deal_promo_pref = GetCarrierDealPromoShown(); 156 const std::string locale = g_browser_process->GetApplicationLocale(); 157 deal_text = deal->GetLocalizedString(locale, "notification_text"); 158 deal_info_url_ = deal->info_url(); 159 deal_topup_url_ = carrier->top_up_url(); 160 } else if (!ShouldShow3gPromoNotification()) { 161 check_for_promo_ = false; 162 return; 163 } 164 165 const chromeos::CellularNetwork* cellular = cros->cellular_network(); 166 DCHECK(cellular); 167 // If we do not know the technology type, do not show the notification yet. 168 // The next NetworkLibrary Manager update should trigger it. 169 if (cellular->network_technology() == NETWORK_TECHNOLOGY_UNKNOWN) 170 return; 171 172 string16 message = l10n_util::GetStringUTF16(IDS_3G_NOTIFICATION_MESSAGE); 173 if (!deal_text.empty()) 174 message = UTF8ToUTF16(deal_text + "\n\n") + message; 175 176 // Use deal URL if it's defined or general "Network Settings" URL. 177 int link_message_id; 178 if (deal_topup_url_.empty()) 179 link_message_id = IDS_OFFLINE_NETWORK_SETTINGS; 180 else 181 link_message_id = IDS_STATUSBAR_NETWORK_VIEW_ACCOUNT; 182 183 ash::NetworkObserver::NetworkType type = 184 (cellular->network_technology() == NETWORK_TECHNOLOGY_LTE || 185 cellular->network_technology() == NETWORK_TECHNOLOGY_LTE_ADVANCED) 186 ? ash::NetworkObserver::NETWORK_CELLULAR_LTE 187 : ash::NetworkObserver::NETWORK_CELLULAR; 188 189 std::vector<string16> links; 190 links.push_back(l10n_util::GetStringUTF16(link_message_id)); 191 if (!deal_info_url_.empty()) 192 links.push_back(l10n_util::GetStringUTF16(IDS_LEARN_MORE)); 193 ash::Shell::GetInstance()->system_tray_notifier()->NotifySetNetworkMessage( 194 listener, ash::NetworkObserver::MESSAGE_DATA_PROMO, 195 type, string16(), message, links); 196 check_for_promo_ = false; 197 SetShow3gPromoNotification(false); 198 if (carrier_deal_promo_pref != kNotificationCountPrefDefault) 199 SetCarrierDealPromoShown(carrier_deal_promo_pref + 1); 200 } 201 } 202 203 void DataPromoNotification::CloseNotification() { 204 ash::Shell::GetInstance()->system_tray_notifier()->NotifyClearNetworkMessage( 205 ash::NetworkObserver::MESSAGE_DATA_PROMO); 206 } 207 208 } // namespace chromeos 209