Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / chromeos / status / data_promo_notification.cc
blob726d10ba5a236accf57dce94e6728dffaa282d82
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.
5 #include "chrome/browser/chromeos/status/data_promo_notification.h"
7 #include "ash/system/system_notifier.h"
8 #include "base/command_line.h"
9 #include "base/prefs/pref_registry_simple.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/chromeos/login/helper.h"
14 #include "chrome/browser/chromeos/mobile_config.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/profiles/profile_manager.h"
17 #include "chrome/browser/ui/browser.h"
18 #include "chrome/browser/ui/browser_list.h"
19 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
20 #include "chrome/browser/ui/singleton_tabs.h"
21 #include "chrome/common/extensions/extension_constants.h"
22 #include "chrome/common/pref_names.h"
23 #include "chrome/grit/generated_resources.h"
24 #include "chromeos/chromeos_switches.h"
25 #include "chromeos/login/login_state.h"
26 #include "chromeos/network/device_state.h"
27 #include "chromeos/network/network_connection_handler.h"
28 #include "chromeos/network/network_event_log.h"
29 #include "chromeos/network/network_state.h"
30 #include "chromeos/network/network_state_handler.h"
31 #include "content/public/browser/user_metrics.h"
32 #include "extensions/browser/extension_registry.h"
33 #include "grit/ui_chromeos_resources.h"
34 #include "third_party/cros_system_api/dbus/service_constants.h"
35 #include "ui/base/l10n/l10n_util.h"
36 #include "ui/base/resource/resource_bundle.h"
37 #include "ui/chromeos/network/network_connect.h"
38 #include "ui/chromeos/network/network_state_notifier.h"
39 #include "ui/message_center/message_center.h"
40 #include "ui/message_center/notification.h"
41 #include "ui/views/view.h"
42 #include "ui/views/widget/widget.h"
44 namespace chromeos {
46 namespace {
48 const char kDataPromoNotificationId[] = "chrome://settings/internet/data_promo";
49 const char kDataSaverNotificationId[] = "chrome://settings/internet/data_saver";
50 const char kDataSaverExtensionUrl[] =
51 "https://chrome.google.com/webstore/detail/"
52 "pfmgfdlgomnbgkofeojodiodmgpgmkac?utm_source=chromeos-datasaver-prompt";
54 const int kNotificationCountPrefDefault = -1;
55 const int kTimesToShowDataSaverPrompt = 2;
57 bool GetBooleanPref(const char* pref_name) {
58 Profile* profile = ProfileManager::GetPrimaryUserProfile();
59 PrefService* prefs = profile->GetPrefs();
60 return prefs->GetBoolean(pref_name);
63 int GetIntegerLocalPref(const char* pref_name) {
64 PrefService* prefs = g_browser_process->local_state();
65 return prefs->GetInteger(pref_name);
68 void SetBooleanPref(const char* pref_name, bool value) {
69 Profile* profile = ProfileManager::GetPrimaryUserProfile();
70 PrefService* prefs = profile->GetPrefs();
71 prefs->SetBoolean(pref_name, value);
74 void SetIntegerLocalPref(const char* pref_name, int value) {
75 PrefService* prefs = g_browser_process->local_state();
76 prefs->SetInteger(pref_name, value);
79 // Returns prefs::kShow3gPromoNotification or false if no active browser.
80 bool ShouldShow3gPromoNotification() {
81 return GetBooleanPref(prefs::kShow3gPromoNotification);
84 void SetShow3gPromoNotification(bool value) {
85 SetBooleanPref(prefs::kShow3gPromoNotification, value);
88 // Returns prefs::kCarrierDealPromoShown which is number of times
89 // carrier deal notification has been shown to users on this machine.
90 int GetCarrierDealPromoShown() {
91 return GetIntegerLocalPref(prefs::kCarrierDealPromoShown);
94 void SetCarrierDealPromoShown(int value) {
95 SetIntegerLocalPref(prefs::kCarrierDealPromoShown, value);
98 // Returns number of times the Data Saver prompt has been displayed.
99 int GetDataSaverPromptsShown() {
100 return ProfileManager::GetActiveUserProfile()->GetPrefs()->GetInteger(
101 prefs::kDataSaverPromptsShown);
104 // Updates number of times the Data Saver prompt has been displayed.
105 void SetDataSaverPromptsShown(int times_shown) {
106 ProfileManager::GetActiveUserProfile()->GetPrefs()->SetInteger(
107 prefs::kDataSaverPromptsShown, times_shown);
110 // Is command line switch set for Data Saver prompt?
111 bool DataSaverSwitchEnabled() {
112 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
113 chromeos::switches::kDisableDataSaverPrompt))
114 return false;
116 return base::CommandLine::ForCurrentProcess()->HasSwitch(
117 chromeos::switches::kEnableDataSaverPrompt);
120 // Is command line switch set for Data Saver demo mode, where we show the prompt
121 // after any change in network properties?
122 bool DataSaverSwitchDemoMode() {
123 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
124 chromeos::switches::kDisableDataSaverPrompt))
125 return false;
127 const std::string value =
128 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
129 chromeos::switches::kEnableDataSaverPrompt);
130 return value == chromeos::switches::kDataSaverPromptDemoMode;
133 const chromeos::MobileConfig::Carrier* GetCarrier(
134 const NetworkState* cellular) {
135 const DeviceState* device = NetworkHandler::Get()->network_state_handler()->
136 GetDeviceState(cellular->device_path());
137 std::string carrier_id = device ? device->home_provider_id() : "";
138 if (carrier_id.empty()) {
139 NET_LOG_ERROR("Empty carrier ID for cellular network",
140 device ? device->path(): "No device");
141 return NULL;
144 chromeos::MobileConfig* config = chromeos::MobileConfig::GetInstance();
145 if (!config->IsReady())
146 return NULL;
148 return config->GetCarrier(carrier_id);
151 const chromeos::MobileConfig::CarrierDeal* GetCarrierDeal(
152 const chromeos::MobileConfig::Carrier* carrier) {
153 const chromeos::MobileConfig::CarrierDeal* deal = carrier->GetDefaultDeal();
154 if (deal) {
155 // Check deal for validity.
156 int carrier_deal_promo_pref = GetCarrierDealPromoShown();
157 if (carrier_deal_promo_pref >= deal->notification_count())
158 return NULL;
159 const std::string locale = g_browser_process->GetApplicationLocale();
160 std::string deal_text = deal->GetLocalizedString(locale,
161 "notification_text");
162 NET_LOG_DEBUG("Carrier Deal Found", deal_text);
163 if (deal_text.empty())
164 return NULL;
166 return deal;
169 void NotificationClicked(const std::string& service_path,
170 const std::string& info_url) {
171 if (!info_url.empty()) {
172 chrome::ScopedTabbedBrowserDisplayer displayer(
173 ProfileManager::GetPrimaryUserProfile(), chrome::HOST_DESKTOP_TYPE_ASH);
174 chrome::ShowSingletonTab(displayer.browser(), GURL(info_url));
175 if (info_url == kDataSaverExtensionUrl)
176 content::RecordAction(base::UserMetricsAction("DataSaverPrompt_Clicked"));
177 } else {
178 ui::NetworkConnect::Get()->ShowNetworkSettingsForPath(service_path);
182 } // namespace
184 ////////////////////////////////////////////////////////////////////////////////
185 // DataPromoNotification
187 DataPromoNotification::DataPromoNotification()
188 : notifications_shown_(false),
189 weak_ptr_factory_(this) {
190 NetworkHandler::Get()->network_state_handler()->AddObserver(this, FROM_HERE);
193 DataPromoNotification::~DataPromoNotification() {
194 if (NetworkHandler::IsInitialized()) {
195 NetworkHandler::Get()->network_state_handler()->RemoveObserver(
196 this, FROM_HERE);
200 void DataPromoNotification::RegisterPrefs(PrefRegistrySimple* registry) {
201 // Carrier deal notification shown count defaults to 0.
202 registry->RegisterIntegerPref(prefs::kCarrierDealPromoShown, 0);
205 void DataPromoNotification::NetworkPropertiesUpdated(
206 const NetworkState* network) {
207 if (!network ||
208 (network->type() != shill::kTypeCellular && !DataSaverSwitchDemoMode()))
209 return;
210 ShowOptionalMobileDataPromoNotification();
213 void DataPromoNotification::DefaultNetworkChanged(const NetworkState* network) {
214 // Call NetworkPropertiesUpdated in case the Cellular network became the
215 // default network.
216 NetworkPropertiesUpdated(network);
219 void DataPromoNotification::ShowOptionalMobileDataPromoNotification() {
220 // Do not show notifications to unauthenticated users, or when requesting a
221 // network connection, or if there's no default_network.
222 if (!LoginState::Get()->IsUserAuthenticated())
223 return;
224 const NetworkState* default_network =
225 NetworkHandler::Get()->network_state_handler()->DefaultNetwork();
226 if (!default_network)
227 return;
228 if (NetworkHandler::Get()->network_connection_handler()->
229 HasPendingConnectRequest())
230 return;
232 if (!DataSaverSwitchDemoMode() &&
233 (notifications_shown_ || default_network->type() != shill::kTypeCellular))
234 return;
236 notifications_shown_ = true;
237 bool data_saver_prompt_shown = ShowDataSaverNotification();
239 // Display a one-time notification on first use of Mobile Data connection, or
240 // if there is a carrier deal defined show that even if user has already seen
241 // generic promo. Show deal regardless of |data_saver_prompt_shown|.
242 int carrier_deal_promo_pref = kNotificationCountPrefDefault;
243 const MobileConfig::CarrierDeal* deal = NULL;
244 const MobileConfig::Carrier* carrier = GetCarrier(default_network);
245 if (carrier)
246 deal = GetCarrierDeal(carrier);
248 base::string16 message =
249 l10n_util::GetStringUTF16(IDS_3G_NOTIFICATION_MESSAGE);
250 std::string info_url;
251 if (deal) {
252 carrier_deal_promo_pref = GetCarrierDealPromoShown();
253 const std::string locale = g_browser_process->GetApplicationLocale();
254 std::string deal_text =
255 deal->GetLocalizedString(locale, "notification_text");
256 message = base::UTF8ToUTF16(deal_text + "\n\n") + message;
257 info_url = deal->info_url();
258 if (info_url.empty() && carrier)
259 info_url = carrier->top_up_url();
260 } else if (data_saver_prompt_shown || !ShouldShow3gPromoNotification()) {
261 return;
264 int icon_id;
265 if (default_network->network_technology() == shill::kNetworkTechnologyLte)
266 icon_id = IDR_AURA_UBER_TRAY_NOTIFICATION_LTE;
267 else
268 icon_id = IDR_AURA_UBER_TRAY_NOTIFICATION_3G;
269 const gfx::Image& icon =
270 ui::ResourceBundle::GetSharedInstance().GetImageNamed(icon_id);
272 message_center::MessageCenter::Get()->AddNotification(
273 message_center::Notification::CreateSystemNotification(
274 kDataPromoNotificationId, base::string16() /* title */, message, icon,
275 ui::NetworkStateNotifier::kNotifierNetwork,
276 base::Bind(&NotificationClicked, default_network->path(), info_url)));
278 SetShow3gPromoNotification(false);
279 if (carrier_deal_promo_pref != kNotificationCountPrefDefault)
280 SetCarrierDealPromoShown(carrier_deal_promo_pref + 1);
283 bool DataPromoNotification::ShowDataSaverNotification() {
284 if (!DataSaverSwitchEnabled())
285 return false;
287 if (message_center::MessageCenter::Get()->FindVisibleNotificationById(
288 kDataSaverNotificationId)) // already showing.
289 return true;
291 int times_shown = GetDataSaverPromptsShown();
292 if (!DataSaverSwitchDemoMode() && times_shown >= kTimesToShowDataSaverPrompt)
293 return false;
295 if (extensions::ExtensionRegistry::Get(ProfileManager::GetActiveUserProfile())
296 ->GetExtensionById(extension_misc::kDataSaverExtensionId,
297 extensions::ExtensionRegistry::EVERYTHING)) {
298 // If extension is installed, disable future prompts.
299 SetDataSaverPromptsShown(kTimesToShowDataSaverPrompt);
300 return false;
303 base::string16 title = l10n_util::GetStringUTF16(IDS_3G_DATASAVER_TITLE);
304 base::string16 message = l10n_util::GetStringUTF16(IDS_3G_DATASAVER_MESSAGE);
305 const gfx::Image& icon =
306 ui::ResourceBundle::GetSharedInstance().GetImageNamed(
307 IDR_AURA_UBER_TRAY_NOTIFICATION_DATASAVER);
309 message_center::MessageCenter::Get()->AddNotification(
310 message_center::Notification::CreateSystemNotification(
311 kDataSaverNotificationId, title, message, icon,
312 ui::NetworkStateNotifier::kNotifierNetwork,
313 base::Bind(&NotificationClicked, "", kDataSaverExtensionUrl)));
314 content::RecordAction(base::UserMetricsAction("DataSaverPrompt_Shown"));
316 if (DataSaverSwitchDemoMode()) {
317 SetDataSaverPromptsShown(0); // demo mode resets times shown counts.
318 SetShow3gPromoNotification(true);
319 } else {
320 SetDataSaverPromptsShown(times_shown + 1);
323 return true;
326 } // namespace chromeos