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