1 // Copyright (c) 2011 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/extensions/apps_promo.h"
6
7 #include "base/command_line.h"
8 #include "base/metrics/histogram.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/prefs/pref_service.h"
11 #include "chrome/browser/ui/webui/shown_sections_handler.h"
12 #include "chrome/common/chrome_switches.h"
13 #include "chrome/common/extensions/extension.h"
14 #include "chrome/common/pref_names.h"
15
16 const int AppsPromo::kDefaultAppsCounterMax = 10;
17
18 // static
RegisterPrefs(PrefService * local_state)19 void AppsPromo::RegisterPrefs(PrefService* local_state) {
20 std::string empty;
21 local_state->RegisterStringPref(prefs::kNTPWebStorePromoId, empty);
22 local_state->RegisterStringPref(prefs::kNTPWebStorePromoHeader, empty);
23 local_state->RegisterStringPref(prefs::kNTPWebStorePromoButton, empty);
24 local_state->RegisterStringPref(prefs::kNTPWebStorePromoLink, empty);
25 local_state->RegisterStringPref(prefs::kNTPWebStorePromoExpire, empty);
26 }
27
28 // static
RegisterUserPrefs(PrefService * prefs)29 void AppsPromo::RegisterUserPrefs(PrefService* prefs) {
30 // Set the default value for the counter to max+1 since we don't install
31 // default apps for new users.
32 prefs->RegisterIntegerPref(
33 prefs::kAppsPromoCounter, kDefaultAppsCounterMax + 1);
34 prefs->RegisterBooleanPref(prefs::kDefaultAppsInstalled, false);
35 prefs->RegisterStringPref(prefs::kNTPWebStorePromoLastId, std::string());
36 }
37
38 // static
ClearPromo()39 void AppsPromo::ClearPromo() {
40 PrefService* local_state = g_browser_process->local_state();
41 local_state->ClearPref(prefs::kNTPWebStorePromoId);
42 local_state->ClearPref(prefs::kNTPWebStorePromoHeader);
43 local_state->ClearPref(prefs::kNTPWebStorePromoButton);
44 local_state->ClearPref(prefs::kNTPWebStorePromoLink);
45 local_state->ClearPref(prefs::kNTPWebStorePromoExpire);
46 }
47
48 // static
GetPromoButtonText()49 std::string AppsPromo::GetPromoButtonText() {
50 PrefService* local_state = g_browser_process->local_state();
51 return local_state->GetString(prefs::kNTPWebStorePromoButton);
52 }
53
54 // static
GetPromoId()55 std::string AppsPromo::GetPromoId() {
56 PrefService* local_state = g_browser_process->local_state();
57 return local_state->GetString(prefs::kNTPWebStorePromoId);
58 }
59
60 // static
GetPromoHeaderText()61 std::string AppsPromo::GetPromoHeaderText() {
62 PrefService* local_state = g_browser_process->local_state();
63 return local_state->GetString(prefs::kNTPWebStorePromoHeader);
64 }
65
66 // static
GetPromoLink()67 GURL AppsPromo::GetPromoLink() {
68 PrefService* local_state = g_browser_process->local_state();
69 return GURL(local_state->GetString(prefs::kNTPWebStorePromoLink));
70 }
71
72 // static
GetPromoExpireText()73 std::string AppsPromo::GetPromoExpireText() {
74 PrefService* local_state = g_browser_process->local_state();
75 return local_state->GetString(prefs::kNTPWebStorePromoExpire);
76 }
77
78 // static
SetPromo(const std::string & id,const std::string & header_text,const std::string & button_text,const GURL & link,const std::string & expire_text)79 void AppsPromo::SetPromo(const std::string& id,
80 const std::string& header_text,
81 const std::string& button_text,
82 const GURL& link,
83 const std::string& expire_text) {
84 PrefService* local_state = g_browser_process->local_state();
85 local_state->SetString(prefs::kNTPWebStorePromoId, id);
86 local_state->SetString(prefs::kNTPWebStorePromoButton, button_text);
87 local_state->SetString(prefs::kNTPWebStorePromoHeader, header_text);
88 local_state->SetString(prefs::kNTPWebStorePromoLink, link.spec());
89 local_state->SetString(prefs::kNTPWebStorePromoExpire, expire_text);
90 }
91
92 // static
IsPromoSupportedForLocale()93 bool AppsPromo::IsPromoSupportedForLocale() {
94 PrefService* local_state = g_browser_process->local_state();
95 // PromoResourceService will clear the promo data if the current locale is
96 // not supported.
97 return local_state->HasPrefPath(prefs::kNTPWebStorePromoId) &&
98 local_state->HasPrefPath(prefs::kNTPWebStorePromoHeader) &&
99 local_state->HasPrefPath(prefs::kNTPWebStorePromoButton) &&
100 local_state->HasPrefPath(prefs::kNTPWebStorePromoLink) &&
101 local_state->HasPrefPath(prefs::kNTPWebStorePromoExpire);
102 }
103
AppsPromo(PrefService * prefs)104 AppsPromo::AppsPromo(PrefService* prefs)
105 : prefs_(prefs) {
106 // Poppit, Entanglement
107 old_default_app_ids_.insert("mcbkbpnkkkipelfledbfocopglifcfmi");
108 old_default_app_ids_.insert("aciahcmjmecflokailenpkdchphgkefd");
109 }
110
~AppsPromo()111 AppsPromo::~AppsPromo() {}
112
ShouldShowPromo(const ExtensionIdSet & installed_ids,bool * just_expired)113 bool AppsPromo::ShouldShowPromo(const ExtensionIdSet& installed_ids,
114 bool* just_expired) {
115 *just_expired = false;
116
117 if (CommandLine::ForCurrentProcess()->HasSwitch(
118 switches::kForceAppsPromoVisible)) {
119 return true;
120 }
121
122 // Don't show the promo if one wasn't served to this locale.
123 if (!IsPromoSupportedForLocale())
124 return false;
125
126 int promo_counter = GetPromoCounter();
127 if (GetDefaultAppsInstalled() && promo_counter <= kDefaultAppsCounterMax) {
128 // If the default apps were installed from a previous Chrome version, we
129 // should still show the promo. If we don't have the exact set of default
130 // apps, this means that the user manually installed or uninstalled one.
131 // We no longer keep track of the default apps once others have been
132 // installed, so expire them immediately.
133 if (old_default_app_ids_ != installed_ids) {
134 ExpireDefaultApps();
135 return false;
136 }
137
138 if (promo_counter == kDefaultAppsCounterMax) {
139 *just_expired = true;
140
141 // The default apps have expired due to inaction, so ping PROMO_EXPIRE.
142 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram,
143 extension_misc::PROMO_EXPIRE,
144 extension_misc::PROMO_BUCKET_BOUNDARY);
145
146 ExpireDefaultApps();
147 return true;
148 } else {
149 SetPromoCounter(++promo_counter);
150 return true;
151 }
152 } else if (installed_ids.empty()) {
153 return true;
154 }
155
156 return false;
157 }
158
ShouldShowAppLauncher(const ExtensionIdSet & installed_ids)159 bool AppsPromo::ShouldShowAppLauncher(const ExtensionIdSet& installed_ids) {
160 // On Chrome OS the default apps are installed via a separate mechanism that
161 // is always enabled. Therefore we always show the launcher.
162 #if defined(OS_CHROME)
163 return true;
164 #else
165
166 // Always show the app launcher if an app is installed.
167 if (!installed_ids.empty())
168 return true;
169
170 // Otherwise, only show the app launcher if there's a promo for this locale.
171 return IsPromoSupportedForLocale();
172 #endif
173 }
174
ExpireDefaultApps()175 void AppsPromo::ExpireDefaultApps() {
176 SetPromoCounter(kDefaultAppsCounterMax + 1);
177 }
178
MaximizeAppsIfFirstView()179 void AppsPromo::MaximizeAppsIfFirstView() {
180 std::string promo_id = GetPromoId();
181
182 // Maximize the apps section of the NTP if this is the first time viewing the
183 // specific promo.
184 if (GetLastPromoId() != promo_id) {
185 prefs_->SetString(prefs::kNTPWebStorePromoLastId, promo_id);
186 ShownSectionsHandler::SetShownSection(prefs_, APPS);
187 }
188 }
189
HidePromo()190 void AppsPromo::HidePromo() {
191 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram,
192 extension_misc::PROMO_CLOSE,
193 extension_misc::PROMO_BUCKET_BOUNDARY);
194
195 // Put the apps section into menu mode, and maximize the recent section.
196 ShownSectionsHandler::SetShownSection(prefs_, MENU_APPS);
197 ShownSectionsHandler::SetShownSection(prefs_, THUMB);
198
199 ExpireDefaultApps();
200 }
201
GetLastPromoId()202 std::string AppsPromo::GetLastPromoId() {
203 return prefs_->GetString(prefs::kNTPWebStorePromoLastId);
204 }
205
SetLastPromoId(const std::string & id)206 void AppsPromo::SetLastPromoId(const std::string& id) {
207 prefs_->SetString(prefs::kNTPWebStorePromoLastId, id);
208 }
209
GetPromoCounter() const210 int AppsPromo::GetPromoCounter() const {
211 return prefs_->GetInteger(prefs::kAppsPromoCounter);
212 }
213
SetPromoCounter(int val)214 void AppsPromo::SetPromoCounter(int val) {
215 prefs_->SetInteger(prefs::kAppsPromoCounter, val);
216 prefs_->ScheduleSavePersistentPrefs();
217 }
218
GetDefaultAppsInstalled() const219 bool AppsPromo::GetDefaultAppsInstalled() const {
220 return prefs_->GetBoolean(prefs::kDefaultAppsInstalled);
221 }
222