data_promo_notification.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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 "base/utf_string_conversions.h" 12#include "chrome/browser/browser_process.h" 13#include "chrome/browser/chromeos/cros/cros_library.h" 14#include "chrome/browser/chromeos/cros/network_library.h" 15#include "chrome/browser/chromeos/login/helper.h" 16#include "chrome/browser/chromeos/login/user_manager.h" 17#include "chrome/browser/chromeos/mobile_config.h" 18#include "chrome/browser/prefs/pref_service.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 "grit/generated_resources.h" 25#include "grit/theme_resources.h" 26#include "ui/base/l10n/l10n_util.h" 27#include "ui/base/resource/resource_bundle.h" 28#include "ui/views/view.h" 29#include "ui/views/widget/widget.h" 30 31namespace { 32 33// Time in milliseconds to delay showing of promo 34// notification when Chrome window is not on screen. 35const int kPromoShowDelayMs = 10000; 36 37const int kNotificationCountPrefDefault = -1; 38 39bool GetBooleanPref(const char* pref_name) { 40 Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord(); 41 PrefService* prefs = profile->GetPrefs(); 42 return prefs->GetBoolean(pref_name); 43} 44 45int GetIntegerLocalPref(const char* pref_name) { 46 PrefService* prefs = g_browser_process->local_state(); 47 return prefs->GetInteger(pref_name); 48} 49 50void SetBooleanPref(const char* pref_name, bool value) { 51 Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord(); 52 PrefService* prefs = profile->GetPrefs(); 53 prefs->SetBoolean(pref_name, value); 54} 55 56void SetIntegerLocalPref(const char* pref_name, int value) { 57 PrefService* prefs = g_browser_process->local_state(); 58 prefs->SetInteger(pref_name, value); 59} 60 61// Returns prefs::kShow3gPromoNotification or false 62// if there's no active browser. 63bool ShouldShow3gPromoNotification() { 64 return GetBooleanPref(prefs::kShow3gPromoNotification); 65} 66 67void SetShow3gPromoNotification(bool value) { 68 SetBooleanPref(prefs::kShow3gPromoNotification, value); 69} 70 71// Returns prefs::kCarrierDealPromoShown which is number of times 72// carrier deal notification has been shown to users on this machine. 73int GetCarrierDealPromoShown() { 74 return GetIntegerLocalPref(prefs::kCarrierDealPromoShown); 75} 76 77void SetCarrierDealPromoShown(int value) { 78 SetIntegerLocalPref(prefs::kCarrierDealPromoShown, value); 79} 80 81const chromeos::MobileConfig::Carrier* GetCarrier( 82 chromeos::NetworkLibrary* cros) { 83 std::string carrier_id = cros->GetCellularHomeCarrierId(); 84 if (carrier_id.empty()) { 85 LOG(ERROR) << "Empty carrier ID with a cellular connected."; 86 return NULL; 87 } 88 89 chromeos::MobileConfig* config = chromeos::MobileConfig::GetInstance(); 90 if (!config->IsReady()) 91 return NULL; 92 93 return config->GetCarrier(carrier_id); 94} 95 96const chromeos::MobileConfig::CarrierDeal* GetCarrierDeal( 97 const chromeos::MobileConfig::Carrier* carrier) { 98 const chromeos::MobileConfig::CarrierDeal* deal = carrier->GetDefaultDeal(); 99 if (deal) { 100 // Check deal for validity. 101 int carrier_deal_promo_pref = GetCarrierDealPromoShown(); 102 if (carrier_deal_promo_pref >= deal->notification_count()) 103 return NULL; 104 const std::string locale = g_browser_process->GetApplicationLocale(); 105 std::string deal_text = deal->GetLocalizedString(locale, 106 "notification_text"); 107 if (deal_text.empty()) 108 return NULL; 109 } 110 return deal; 111} 112 113} // namespace 114 115namespace chromeos { 116 117//////////////////////////////////////////////////////////////////////////////// 118// DataPromoNotification 119 120DataPromoNotification::DataPromoNotification() 121 : check_for_promo_(true), 122 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { 123} 124 125DataPromoNotification::~DataPromoNotification() { 126 CloseNotification(); 127} 128 129void DataPromoNotification::RegisterPrefs(PrefService* local_state) { 130 // Carrier deal notification shown count defaults to 0. 131 local_state->RegisterIntegerPref(prefs::kCarrierDealPromoShown, 0); 132} 133 134void DataPromoNotification::ShowOptionalMobileDataPromoNotification( 135 NetworkLibrary* cros, 136 views::View* host, 137 ash::NetworkTrayDelegate* listener) { 138 // Display one-time notification for non-Guest users on first use 139 // of Mobile Data connection or if there's a carrier deal defined 140 // show that even if user has already seen generic promo. 141 if (UserManager::Get()->IsUserLoggedIn() && 142 !UserManager::Get()->IsLoggedInAsGuest() && 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 gfx::Rect button_bounds = host->GetBoundsInScreen(); 166 // StatusArea button Y position is usually -1, fix it so that 167 // Contains() method for screen bounds works correctly. 168 button_bounds.set_y(button_bounds.y() + 1); 169 gfx::Rect screen_bounds(chromeos::CalculateScreenBounds(gfx::Size())); 170 171 // Chrome window is initialized in visible state off screen and then is 172 // moved into visible screen area. Make sure that we're on screen 173 // so that bubble is shown correctly. 174 if (!screen_bounds.Contains(button_bounds)) { 175 // If we're not on screen yet, delay notification display. 176 // It may be shown earlier, on next NetworkLibrary callback processing. 177 if (!weak_ptr_factory_.HasWeakPtrs()) { 178 MessageLoop::current()->PostDelayedTask(FROM_HERE, 179 base::Bind( 180 &DataPromoNotification::ShowOptionalMobileDataPromoNotification, 181 weak_ptr_factory_.GetWeakPtr(), 182 cros, 183 host, 184 listener), 185 base::TimeDelta::FromMilliseconds(kPromoShowDelayMs)); 186 } 187 return; 188 } 189 190 string16 message = l10n_util::GetStringUTF16(IDS_3G_NOTIFICATION_MESSAGE); 191 if (!deal_text.empty()) 192 message = UTF8ToUTF16(deal_text + "\n\n") + message; 193 194 // Use deal URL if it's defined or general "Network Settings" URL. 195 int link_message_id; 196 if (deal_topup_url_.empty()) 197 link_message_id = IDS_OFFLINE_NETWORK_SETTINGS; 198 else 199 link_message_id = IDS_STATUSBAR_NETWORK_VIEW_ACCOUNT; 200 201 std::vector<string16> links; 202 links.push_back(l10n_util::GetStringUTF16(link_message_id)); 203 if (!deal_info_url_.empty()) 204 links.push_back(l10n_util::GetStringUTF16(IDS_LEARN_MORE)); 205 if (ash::Shell::GetInstance()->system_tray()->network_observer()) { 206 ash::Shell::GetInstance()->system_tray()->network_observer()-> 207 SetNetworkMessage(listener, ash::NetworkObserver::MESSAGE_DATA_PROMO, 208 string16(), message, links); 209 } 210 211 check_for_promo_ = false; 212 SetShow3gPromoNotification(false); 213 if (carrier_deal_promo_pref != kNotificationCountPrefDefault) 214 SetCarrierDealPromoShown(carrier_deal_promo_pref + 1); 215 } 216} 217 218void DataPromoNotification::CloseNotification() { 219 if (ash::Shell::GetInstance()->status_area_widget() && 220 ash::Shell::GetInstance()->system_tray()->network_observer()) { 221 ash::Shell::GetInstance()->system_tray()->network_observer()-> 222 ClearNetworkMessage(ash::NetworkObserver::MESSAGE_DATA_PROMO); 223 } 224} 225 226} // namespace chromeos 227