data_promo_notification.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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
32namespace {
33
34// Time in milliseconds to delay showing of promo
35// notification when Chrome window is not on screen.
36const int kPromoShowDelayMs = 10000;
37
38const int kNotificationCountPrefDefault = -1;
39
40bool GetBooleanPref(const char* pref_name) {
41  Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord();
42  PrefService* prefs = profile->GetPrefs();
43  return prefs->GetBoolean(pref_name);
44}
45
46int GetIntegerLocalPref(const char* pref_name) {
47  PrefService* prefs = g_browser_process->local_state();
48  return prefs->GetInteger(pref_name);
49}
50
51void 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
57void 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.
64bool ShouldShow3gPromoNotification() {
65  return GetBooleanPref(prefs::kShow3gPromoNotification);
66}
67
68void 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.
74int GetCarrierDealPromoShown() {
75  return GetIntegerLocalPref(prefs::kCarrierDealPromoShown);
76}
77
78void SetCarrierDealPromoShown(int value) {
79  SetIntegerLocalPref(prefs::kCarrierDealPromoShown, value);
80}
81
82const 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
97const 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
116namespace chromeos {
117
118////////////////////////////////////////////////////////////////////////////////
119// DataPromoNotification
120
121DataPromoNotification::DataPromoNotification()
122    : check_for_promo_(true),
123      weak_ptr_factory_(this) {
124}
125
126DataPromoNotification::~DataPromoNotification() {
127  CloseNotification();
128}
129
130void DataPromoNotification::RegisterPrefs(PrefRegistrySimple* registry) {
131  // Carrier deal notification shown count defaults to 0.
132  registry->RegisterIntegerPref(prefs::kCarrierDealPromoShown, 0);
133}
134
135void 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
203void DataPromoNotification::CloseNotification() {
204  ash::Shell::GetInstance()->system_tray_notifier()->NotifyClearNetworkMessage(
205      ash::NetworkObserver::MESSAGE_DATA_PROMO);
206}
207
208}  // namespace chromeos
209