| Index: chrome/browser/extensions/apps_promo.cc
|
| diff --git a/chrome/browser/extensions/apps_promo.cc b/chrome/browser/extensions/apps_promo.cc
|
| index a137bacc23dec2b399f9e50ec0bf7fef8855c319..390b575a9a6064e99e1559f56ab9f7a200988d74 100644
|
| --- a/chrome/browser/extensions/apps_promo.cc
|
| +++ b/chrome/browser/extensions/apps_promo.cc
|
| @@ -4,21 +4,44 @@
|
|
|
| #include "chrome/browser/extensions/apps_promo.h"
|
|
|
| +#include "base/base64.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/profiles/profile.h"
|
| #include "chrome/browser/ui/webui/ntp/shown_sections_handler.h"
|
| #include "chrome/common/chrome_switches.h"
|
| #include "chrome/common/extensions/extension.h"
|
| +#include "chrome/common/chrome_notification_types.h"
|
| #include "chrome/common/pref_names.h"
|
| +#include "content/common/url_constants.h"
|
| +#include "content/common/notification_service.h"
|
| +#include "net/base/load_flags.h"
|
| +#include "net/url_request/url_request_status.h"
|
|
|
| const int AppsPromo::kDefaultAppsCounterMax = 10;
|
|
|
| namespace {
|
|
|
| // The default logo for the promo.
|
| -const char kDefaultPromoLogo[] = "chrome://theme/IDR_WEBSTORE_ICON";
|
| +const char kDefaultLogo[] = "chrome://theme/IDR_WEBSTORE_ICON";
|
| +
|
| +// The default promo data (this is only used for testing with
|
| +// --force-apps-promo-visible).
|
| +const char kDefaultHeader[] = "Browse thousands of apps and games for Chrome";
|
| +const char kDefaultButton[] = "Visit the Chrome Web Store";
|
| +const char kDefaultExpire[] = "No thanks";
|
| +const char kDefaultLink[] = "https://chrome.google.com/webstore";
|
| +
|
| +// Http success status code.
|
| +const int kHttpSuccess = 200;
|
| +
|
| +// The match pattern for valid logo URLs.
|
| +const char kValidLogoPattern[] = "https://*.google.com/*.png";
|
| +
|
| +// The prefix for 'data' URL images.
|
| +const char kPNGDataURLPrefix[] = "data:image/png;base64,";
|
|
|
| // Returns the string pref at |path|, using |fallback| as the default (if there
|
| // is no pref value present). |fallback| is used for debugging in concert with
|
| @@ -35,6 +58,24 @@ std::string GetStringPref(const char* path, const std::string& fallback) {
|
|
|
| } // namespace
|
|
|
| +AppsPromo::PromoData::PromoData() {}
|
| +AppsPromo::PromoData::PromoData(const std::string& id,
|
| + const std::string& header,
|
| + const std::string& button,
|
| + const GURL& link,
|
| + const std::string& expire,
|
| + const GURL& logo,
|
| + const int user_group)
|
| + : id(id),
|
| + header(header),
|
| + button(button),
|
| + link(link),
|
| + expire(expire),
|
| + logo(logo),
|
| + user_group(user_group) {}
|
| +
|
| +AppsPromo::PromoData::~PromoData() {}
|
| +
|
| // static
|
| void AppsPromo::RegisterPrefs(PrefService* local_state) {
|
| std::string empty;
|
| @@ -44,6 +85,7 @@ void AppsPromo::RegisterPrefs(PrefService* local_state) {
|
| local_state->RegisterStringPref(prefs::kNTPWebStorePromoButton, empty);
|
| local_state->RegisterStringPref(prefs::kNTPWebStorePromoLink, empty);
|
| local_state->RegisterStringPref(prefs::kNTPWebStorePromoLogo, empty);
|
| + local_state->RegisterStringPref(prefs::kNTPWebStorePromoLogoSource, empty);
|
| local_state->RegisterStringPref(prefs::kNTPWebStorePromoExpire, empty);
|
| local_state->RegisterIntegerPref(prefs::kNTPWebStorePromoUserGroup, 0);
|
| }
|
| @@ -62,21 +104,8 @@ void AppsPromo::RegisterUserPrefs(PrefService* prefs) {
|
| std::string(),
|
| PrefService::UNSYNCABLE_PREF);
|
| prefs->RegisterBooleanPref(prefs::kNTPHideWebStorePromo,
|
| - false,
|
| - PrefService::UNSYNCABLE_PREF);
|
| -}
|
| -
|
| -// static
|
| -void AppsPromo::ClearPromo() {
|
| - PrefService* local_state = g_browser_process->local_state();
|
| - local_state->ClearPref(prefs::kNTPWebStoreEnabled);
|
| - local_state->ClearPref(prefs::kNTPWebStorePromoId);
|
| - local_state->ClearPref(prefs::kNTPWebStorePromoHeader);
|
| - local_state->ClearPref(prefs::kNTPWebStorePromoButton);
|
| - local_state->ClearPref(prefs::kNTPWebStorePromoLink);
|
| - local_state->ClearPref(prefs::kNTPWebStorePromoLogo);
|
| - local_state->ClearPref(prefs::kNTPWebStorePromoExpire);
|
| - local_state->ClearPref(prefs::kNTPWebStorePromoUserGroup);
|
| + false,
|
| + PrefService::UNSYNCABLE_PREF);
|
| }
|
|
|
| // static
|
| @@ -100,68 +129,68 @@ bool AppsPromo::IsWebStoreSupportedForLocale() {
|
| }
|
|
|
| // static
|
| -std::string AppsPromo::GetPromoButtonText() {
|
| - return GetStringPref(prefs::kNTPWebStorePromoButton, "Click here now");
|
| +void AppsPromo::SetWebStoreSupportedForLocale(bool supported) {
|
| + PrefService* local_state = g_browser_process->local_state();
|
| + local_state->SetBoolean(prefs::kNTPWebStoreEnabled, supported);
|
| }
|
|
|
| // static
|
| -std::string AppsPromo::GetPromoId() {
|
| - return GetStringPref(prefs::kNTPWebStorePromoId, "");
|
| +void AppsPromo::ClearPromo() {
|
| + PrefService* local_state = g_browser_process->local_state();
|
| + local_state->ClearPref(prefs::kNTPWebStoreEnabled);
|
| + local_state->ClearPref(prefs::kNTPWebStorePromoId);
|
| + local_state->ClearPref(prefs::kNTPWebStorePromoHeader);
|
| + local_state->ClearPref(prefs::kNTPWebStorePromoButton);
|
| + local_state->ClearPref(prefs::kNTPWebStorePromoLink);
|
| + local_state->ClearPref(prefs::kNTPWebStorePromoLogo);
|
| + local_state->ClearPref(prefs::kNTPWebStorePromoLogoSource);
|
| + local_state->ClearPref(prefs::kNTPWebStorePromoExpire);
|
| + local_state->ClearPref(prefs::kNTPWebStorePromoUserGroup);
|
| }
|
|
|
| // static
|
| -std::string AppsPromo::GetPromoHeaderText() {
|
| - return GetStringPref(prefs::kNTPWebStorePromoHeader, "Get great apps!");
|
| -}
|
| +AppsPromo::PromoData AppsPromo::GetPromo() {
|
| + PromoData data;
|
| + PrefService* local_state = g_browser_process->local_state();
|
|
|
| -// static
|
| -GURL AppsPromo::GetPromoLink() {
|
| - return GURL(GetStringPref(prefs::kNTPWebStorePromoLink,
|
| - "https://chrome.google.com/webstore"));
|
| -}
|
| + data.id = GetStringPref(prefs::kNTPWebStorePromoId, "");
|
| + data.link = GURL(GetStringPref(prefs::kNTPWebStorePromoLink, kDefaultLink));
|
| + data.user_group = local_state->GetInteger(prefs::kNTPWebStorePromoUserGroup);
|
| + data.header = GetStringPref(prefs::kNTPWebStorePromoHeader, kDefaultHeader);
|
| + data.button = GetStringPref(prefs::kNTPWebStorePromoButton, kDefaultButton);
|
| + data.expire = GetStringPref(prefs::kNTPWebStorePromoExpire, kDefaultExpire);
|
|
|
| -// static
|
| -GURL AppsPromo::GetPromoLogo() {
|
| - PrefService* local_state = g_browser_process->local_state();
|
| GURL logo_url(local_state->GetString(prefs::kNTPWebStorePromoLogo));
|
| - if (logo_url.is_valid() && logo_url.SchemeIs("data"))
|
| - return logo_url;
|
| - return GURL(kDefaultPromoLogo);
|
| -}
|
| + if (logo_url.is_valid() && logo_url.SchemeIs(chrome::kDataScheme))
|
| + data.logo = logo_url;
|
| + else
|
| + data.logo = GURL(kDefaultLogo);
|
|
|
| -// static
|
| -std::string AppsPromo::GetPromoExpireText() {
|
| - return GetStringPref(prefs::kNTPWebStorePromoExpire, "No thanks.");
|
| + return data;
|
| }
|
|
|
| // static
|
| -int AppsPromo::GetPromoUserGroup() {
|
| +void AppsPromo::SetPromo(AppsPromo::PromoData data) {
|
| PrefService* local_state = g_browser_process->local_state();
|
| - return local_state->GetInteger(prefs::kNTPWebStorePromoUserGroup);
|
| + local_state->SetString(prefs::kNTPWebStorePromoId, data.id);
|
| + local_state->SetString(prefs::kNTPWebStorePromoButton, data.button);
|
| + local_state->SetString(prefs::kNTPWebStorePromoHeader, data.header);
|
| + local_state->SetString(prefs::kNTPWebStorePromoLink, data.link.spec());
|
| + local_state->SetString(prefs::kNTPWebStorePromoLogo, data.logo.spec());
|
| + local_state->SetString(prefs::kNTPWebStorePromoExpire, data.expire);
|
| + local_state->SetInteger(prefs::kNTPWebStorePromoUserGroup, data.user_group);
|
| }
|
|
|
| // 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,
|
| - const GURL& logo,
|
| - const int user_group) {
|
| - 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::kNTPWebStorePromoLogo, logo.spec());
|
| - local_state->SetString(prefs::kNTPWebStorePromoExpire, expire_text);
|
| - local_state->SetInteger(prefs::kNTPWebStorePromoUserGroup, user_group);
|
| +GURL AppsPromo::GetSourcePromoLogoURL() {
|
| + return GURL(GetStringPref(prefs::kNTPWebStorePromoLogoSource, ""));
|
| }
|
|
|
| // static
|
| -void AppsPromo::SetWebStoreSupportedForLocale(bool supported) {
|
| +void AppsPromo::SetSourcePromoLogoURL(GURL logo_source) {
|
| PrefService* local_state = g_browser_process->local_state();
|
| - local_state->SetBoolean(prefs::kNTPWebStoreEnabled, supported);
|
| + local_state->SetString(prefs::kNTPWebStorePromoLogoSource,
|
| + logo_source.spec());
|
| }
|
|
|
| AppsPromo::AppsPromo(PrefService* prefs)
|
| @@ -246,15 +275,14 @@ void AppsPromo::ExpireDefaultApps() {
|
| }
|
|
|
| void AppsPromo::MaximizeAppsIfNecessary() {
|
| - std::string promo_id = GetPromoId();
|
| - int maximize_setting = GetPromoUserGroup();
|
| + PromoData promo = GetPromo();
|
|
|
| // Maximize the apps section of the NTP if this is the first time viewing the
|
| // specific promo and the current user group is targetted.
|
| - if (GetLastPromoId() != promo_id) {
|
| - if ((maximize_setting & GetCurrentUserGroup()) != 0)
|
| + if (GetLastPromoId() != promo.id) {
|
| + if ((promo.user_group & GetCurrentUserGroup()) != 0)
|
| ShownSectionsHandler::SetShownSection(prefs_, APPS);
|
| - SetLastPromoId(promo_id);
|
| + SetLastPromoId(promo.id);
|
| }
|
| }
|
|
|
| @@ -297,3 +325,76 @@ AppsPromo::UserGroup AppsPromo::GetCurrentUserGroup() const {
|
| CHECK(last_promo_id);
|
| return last_promo_id->IsDefaultValue() ? USERS_NEW : USERS_EXISTING;
|
| }
|
| +
|
| +AppsPromoLogoFetcher::AppsPromoLogoFetcher(
|
| + Profile* profile,
|
| + AppsPromo::PromoData promo_data)
|
| + : profile_(profile),
|
| + promo_data_(promo_data) {
|
| + if (SupportsLogoURL()) {
|
| + if (HaveCachedLogo()) {
|
| + promo_data_.logo = AppsPromo::GetPromo().logo;
|
| + SavePromo();
|
| + } else {
|
| + FetchLogo();
|
| + }
|
| + } else {
|
| + // We only care about the source URL when this fetches the logo.
|
| + AppsPromo::SetSourcePromoLogoURL(GURL());
|
| + SavePromo();
|
| + }
|
| +}
|
| +
|
| +AppsPromoLogoFetcher::~AppsPromoLogoFetcher() {}
|
| +
|
| +void AppsPromoLogoFetcher::OnURLFetchComplete(const URLFetcher* source) {
|
| + std::string data;
|
| + std::string base64_data;
|
| +
|
| + CHECK(source == url_fetcher_.get());
|
| + CHECK(source->GetResponseAsString(&data));
|
| +
|
| + if (source->status().is_success() &&
|
| + source->response_code() == kHttpSuccess &&
|
| + base::Base64Encode(data, &base64_data)) {
|
| + AppsPromo::SetSourcePromoLogoURL(promo_data_.logo);
|
| + promo_data_.logo = GURL(kPNGDataURLPrefix + base64_data);
|
| + } else {
|
| + // The logo wasn't downloaded correctly or we failed to encode it in
|
| + // base64. Reset the source URL so we fetch it again next time. AppsPromo
|
| + // will revert to the default logo.
|
| + AppsPromo::SetSourcePromoLogoURL(GURL());
|
| + }
|
| +
|
| + SavePromo();
|
| +}
|
| +
|
| +void AppsPromoLogoFetcher::FetchLogo() {
|
| + CHECK(promo_data_.logo.scheme() == chrome::kHttpsScheme);
|
| +
|
| + url_fetcher_.reset(URLFetcher::Create(
|
| + 0, promo_data_.logo, URLFetcher::GET, this));
|
| + url_fetcher_->set_request_context(
|
| + g_browser_process->system_request_context());
|
| + url_fetcher_->set_load_flags(net::LOAD_DO_NOT_SEND_COOKIES |
|
| + net::LOAD_DO_NOT_SAVE_COOKIES);
|
| + url_fetcher_->Start();
|
| +}
|
| +
|
| +bool AppsPromoLogoFetcher::HaveCachedLogo() {
|
| + return promo_data_.logo == AppsPromo::GetSourcePromoLogoURL();
|
| +}
|
| +
|
| +void AppsPromoLogoFetcher::SavePromo() {
|
| + AppsPromo::SetPromo(promo_data_);
|
| +
|
| + NotificationService::current()->Notify(
|
| + chrome::NOTIFICATION_WEB_STORE_PROMO_LOADED,
|
| + Source<Profile>(profile_),
|
| + NotificationService::NoDetails());
|
| +}
|
| +
|
| +bool AppsPromoLogoFetcher::SupportsLogoURL() {
|
| + URLPattern allowed_urls(URLPattern::SCHEME_HTTPS, kValidLogoPattern);
|
| + return allowed_urls.MatchesURL(promo_data_.logo);
|
| +}
|
|
|