// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/apps_promo.h"
#include "base/command_line.h"
#include "base/metrics/histogram.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/ui/webui/shown_sections_handler.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/pref_names.h"
const int AppsPromo::kDefaultAppsCounterMax = 10;
// static
void AppsPromo::RegisterPrefs(PrefService* local_state) {
std::string empty;
local_state->RegisterStringPref(prefs::kNTPWebStorePromoId, empty);
local_state->RegisterStringPref(prefs::kNTPWebStorePromoHeader, empty);
local_state->RegisterStringPref(prefs::kNTPWebStorePromoButton, empty);
local_state->RegisterStringPref(prefs::kNTPWebStorePromoLink, empty);
local_state->RegisterStringPref(prefs::kNTPWebStorePromoExpire, empty);
}
// static
void AppsPromo::RegisterUserPrefs(PrefService* prefs) {
// Set the default value for the counter to max+1 since we don't install
// default apps for new users.
prefs->RegisterIntegerPref(
prefs::kAppsPromoCounter, kDefaultAppsCounterMax + 1);
prefs->RegisterBooleanPref(prefs::kDefaultAppsInstalled, false);
prefs->RegisterStringPref(prefs::kNTPWebStorePromoLastId, std::string());
}
// static
void AppsPromo::ClearPromo() {
PrefService* local_state = g_browser_process->local_state();
local_state->ClearPref(prefs::kNTPWebStorePromoId);
local_state->ClearPref(prefs::kNTPWebStorePromoHeader);
local_state->ClearPref(prefs::kNTPWebStorePromoButton);
local_state->ClearPref(prefs::kNTPWebStorePromoLink);
local_state->ClearPref(prefs::kNTPWebStorePromoExpire);
}
// static
std::string AppsPromo::GetPromoButtonText() {
PrefService* local_state = g_browser_process->local_state();
return local_state->GetString(prefs::kNTPWebStorePromoButton);
}
// static
std::string AppsPromo::GetPromoId() {
PrefService* local_state = g_browser_process->local_state();
return local_state->GetString(prefs::kNTPWebStorePromoId);
}
// static
std::string AppsPromo::GetPromoHeaderText() {
PrefService* local_state = g_browser_process->local_state();
return local_state->GetString(prefs::kNTPWebStorePromoHeader);
}
// static
GURL AppsPromo::GetPromoLink() {
PrefService* local_state = g_browser_process->local_state();
return GURL(local_state->GetString(prefs::kNTPWebStorePromoLink));
}
// static
std::string AppsPromo::GetPromoExpireText() {
PrefService* local_state = g_browser_process->local_state();
return local_state->GetString(prefs::kNTPWebStorePromoExpire);
}
// static
void AppsPromo::SetPromo(const std::string& id,
const std::string& header_text,
const std::string& button_text,
const GURL& link,
const std::string& expire_text) {
PrefService* local_state = g_browser_process->local_state();
local_state->SetString(prefs::kNTPWebStorePromoId, id);
local_state->SetString(prefs::kNTPWebStorePromoButton, button_text);
local_state->SetString(prefs::kNTPWebStorePromoHeader, header_text);
local_state->SetString(prefs::kNTPWebStorePromoLink, link.spec());
local_state->SetString(prefs::kNTPWebStorePromoExpire, expire_text);
}
// static
bool AppsPromo::IsPromoSupportedForLocale() {
PrefService* local_state = g_browser_process->local_state();
// PromoResourceService will clear the promo data if the current locale is
// not supported.
return local_state->HasPrefPath(prefs::kNTPWebStorePromoId) &&
local_state->HasPrefPath(prefs::kNTPWebStorePromoHeader) &&
local_state->HasPrefPath(prefs::kNTPWebStorePromoButton) &&
local_state->HasPrefPath(prefs::kNTPWebStorePromoLink) &&
local_state->HasPrefPath(prefs::kNTPWebStorePromoExpire);
}
AppsPromo::AppsPromo(PrefService* prefs)
: prefs_(prefs) {
// Poppit, Entanglement
old_default_app_ids_.insert("mcbkbpnkkkipelfledbfocopglifcfmi");
old_default_app_ids_.insert("aciahcmjmecflokailenpkdchphgkefd");
}
AppsPromo::~AppsPromo() {}
bool AppsPromo::ShouldShowPromo(const ExtensionIdSet& installed_ids,
bool* just_expired) {
*just_expired = false;
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kForceAppsPromoVisible)) {
return true;
}
// Don't show the promo if one wasn't served to this locale.
if (!IsPromoSupportedForLocale())
return false;
int promo_counter = GetPromoCounter();
if (GetDefaultAppsInstalled() && promo_counter <= kDefaultAppsCounterMax) {
// If the default apps were installed from a previous Chrome version, we
// should still show the promo. If we don't have the exact set of default
// apps, this means that the user manually installed or uninstalled one.
// We no longer keep track of the default apps once others have been
// installed, so expire them immediately.
if (old_default_app_ids_ != installed_ids) {
ExpireDefaultApps();
return false;
}
if (promo_counter == kDefaultAppsCounterMax) {
*just_expired = true;
// The default apps have expired due to inaction, so ping PROMO_EXPIRE.
UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram,
extension_misc::PROMO_EXPIRE,
extension_misc::PROMO_BUCKET_BOUNDARY);
ExpireDefaultApps();
return true;
} else {
SetPromoCounter(++promo_counter);
return true;
}
} else if (installed_ids.empty()) {
return true;
}
return false;
}
bool AppsPromo::ShouldShowAppLauncher(const ExtensionIdSet& installed_ids) {
// On Chrome OS the default apps are installed via a separate mechanism that
// is always enabled. Therefore we always show the launcher.
#if defined(OS_CHROME)
return true;
#else
// Always show the app launcher if an app is installed.
if (!installed_ids.empty())
return true;
// Otherwise, only show the app launcher if there's a promo for this locale.
return IsPromoSupportedForLocale();
#endif
}
void AppsPromo::ExpireDefaultApps() {
SetPromoCounter(kDefaultAppsCounterMax + 1);
}
void AppsPromo::MaximizeAppsIfFirstView() {
std::string promo_id = GetPromoId();
// Maximize the apps section of the NTP if this is the first time viewing the
// specific promo.
if (GetLastPromoId() != promo_id) {
prefs_->SetString(prefs::kNTPWebStorePromoLastId, promo_id);
ShownSectionsHandler::SetShownSection(prefs_, APPS);
}
}
void AppsPromo::HidePromo() {
UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram,
extension_misc::PROMO_CLOSE,
extension_misc::PROMO_BUCKET_BOUNDARY);
// Put the apps section into menu mode, and maximize the recent section.
ShownSectionsHandler::SetShownSection(prefs_, MENU_APPS);
ShownSectionsHandler::SetShownSection(prefs_, THUMB);
ExpireDefaultApps();
}
std::string AppsPromo::GetLastPromoId() {
return prefs_->GetString(prefs::kNTPWebStorePromoLastId);
}
void AppsPromo::SetLastPromoId(const std::string& id) {
prefs_->SetString(prefs::kNTPWebStorePromoLastId, id);
}
int AppsPromo::GetPromoCounter() const {
return prefs_->GetInteger(prefs::kAppsPromoCounter);
}
void AppsPromo::SetPromoCounter(int val) {
prefs_->SetInteger(prefs::kAppsPromoCounter, val);
prefs_->ScheduleSavePersistentPrefs();
}
bool AppsPromo::GetDefaultAppsInstalled() const {
return prefs_->GetBoolean(prefs::kDefaultAppsInstalled);
}