Home | History | Annotate | Download | only in extensions
      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
     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
     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
     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
     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
     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
     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
     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
     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
     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
     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 
    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 
    111 AppsPromo::~AppsPromo() {}
    112 
    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 
    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 
    175 void AppsPromo::ExpireDefaultApps() {
    176   SetPromoCounter(kDefaultAppsCounterMax + 1);
    177 }
    178 
    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 
    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 
    202 std::string AppsPromo::GetLastPromoId() {
    203   return prefs_->GetString(prefs::kNTPWebStorePromoLastId);
    204 }
    205 
    206 void AppsPromo::SetLastPromoId(const std::string& id) {
    207   prefs_->SetString(prefs::kNTPWebStorePromoLastId, id);
    208 }
    209 
    210 int AppsPromo::GetPromoCounter() const {
    211   return prefs_->GetInteger(prefs::kAppsPromoCounter);
    212 }
    213 
    214 void AppsPromo::SetPromoCounter(int val) {
    215   prefs_->SetInteger(prefs::kAppsPromoCounter, val);
    216   prefs_->ScheduleSavePersistentPrefs();
    217 }
    218 
    219 bool AppsPromo::GetDefaultAppsInstalled() const {
    220   return prefs_->GetBoolean(prefs::kDefaultAppsInstalled);
    221 }
    222