Chromium Code Reviews| Index: chrome/browser/web_resource/promo_resource_service.cc |
| diff --git a/chrome/browser/web_resource/promo_resource_service.cc b/chrome/browser/web_resource/promo_resource_service.cc |
| index 947fe95940de9b6bf975126e89c7e6f77c85b041..f3a96ef4ec39a4c7020cacc2e2b29e87b0ec8a97 100644 |
| --- a/chrome/browser/web_resource/promo_resource_service.cc |
| +++ b/chrome/browser/web_resource/promo_resource_service.cc |
| @@ -9,6 +9,7 @@ |
| #include "base/time.h" |
| #include "base/values.h" |
| #include "chrome/browser/browser_process.h" |
| +#include "chrome/browser/extensions/apps_promo.h" |
| #include "chrome/browser/platform_util.h" |
| #include "chrome/browser/prefs/pref_service.h" |
| #include "chrome/browser/profiles/profile.h" |
| @@ -17,6 +18,7 @@ |
| #include "content/browser/browser_thread.h" |
| #include "content/common/notification_service.h" |
| #include "content/common/notification_type.h" |
| +#include "googleurl/src/gurl.h" |
| namespace { |
| @@ -34,13 +36,17 @@ static const int kNTPPromoGroupSize = 16; |
| // Maximum number of hours for each time slice (4 weeks). |
| static const int kMaxTimeSliceHours = 24 * 7 * 4; |
| -// Used to determine which build type should be shown a given promo. |
| -enum BuildType { |
| - NO_BUILD = 0, |
| - DEV_BUILD = 1, |
| - BETA_BUILD = 1 << 1, |
| - STABLE_BUILD = 1 << 2, |
| -}; |
| +// The version of the service (used to expire the cache when upgrading Chrome |
| +// to versions with different types of promos). |
| +static const int kPromoServiceVersion = 1; |
| + |
| +// Properties used by the server. |
| +static const char kAnswerIdProperty[] = "answer_id"; |
| +static const char kWebStoreHeaderProperty[] = "answer1"; |
| +static const char kWebStoreButtonProperty[] = "answer2"; |
| +static const char kWebStoreLinkProperty[] = "answer3"; |
| +static const char kWebStoreExpireProperty[] = "answer4"; |
| +static const char kWebStoreBuildsProperty[] = "inproduct"; |
| } // namespace |
| @@ -49,6 +55,44 @@ enum BuildType { |
| const char* PromoResourceService::kDefaultPromoResourceServer = |
| "https://www.google.com/support/chrome/bin/topic/1142433/inproduct?hl="; |
| +// static |
| +void PromoResourceService::RegisterPrefs(PrefService* local_state) { |
| + local_state->RegisterIntegerPref(prefs::kNTPPromoVersion, 0); |
| + local_state->RegisterStringPref(prefs::kNTPPromoLocale, std::string()); |
| +} |
| + |
| +// static |
| +void PromoResourceService::RegisterUserPrefs(PrefService* prefs) { |
| + prefs->RegisterDoublePref(prefs::kNTPCustomLogoStart, 0); |
| + prefs->RegisterDoublePref(prefs::kNTPCustomLogoEnd, 0); |
| + prefs->RegisterDoublePref(prefs::kNTPPromoStart, 0); |
| + prefs->RegisterDoublePref(prefs::kNTPPromoEnd, 0); |
| + prefs->RegisterStringPref(prefs::kNTPPromoLine, std::string()); |
| + prefs->RegisterBooleanPref(prefs::kNTPPromoClosed, false); |
| + prefs->RegisterIntegerPref(prefs::kNTPPromoGroup, -1); |
| + prefs->RegisterIntegerPref(prefs::kNTPPromoBuild, |
| + CANARY_BUILD | DEV_BUILD | BETA_BUILD | STABLE_BUILD); |
| + prefs->RegisterIntegerPref(prefs::kNTPPromoGroupTimeSlice, 0); |
| +} |
| + |
| +// static |
| +bool PromoResourceService::IsBuildTargeted(const std::string& channel, |
| + int builds_allowed) { |
| + if (builds_allowed == NO_BUILD) |
| + return false; |
| + if (channel == "canary" || channel == "canary-m") { |
| + return (CANARY_BUILD & builds_allowed) != 0; |
| + } else if (channel == "dev" || channel == "dev-m") { |
| + return (DEV_BUILD & builds_allowed) != 0; |
| + } else if (channel == "beta" || channel == "beta-m") { |
| + return (BETA_BUILD & builds_allowed) != 0; |
| + } else if (channel == "" || channel == "m") { |
| + return (STABLE_BUILD & builds_allowed) != 0; |
| + } else { |
| + return false; |
| + } |
| +} |
| + |
| PromoResourceService::PromoResourceService(Profile* profile) |
| : WebResourceService(profile, |
| profile->GetPrefs(), |
| @@ -58,34 +102,33 @@ PromoResourceService::PromoResourceService(Profile* profile) |
| prefs::kNTPPromoResourceCacheUpdate, |
| kStartResourceFetchDelay, |
| kCacheUpdateDelay), |
| - web_resource_cache_(NULL) { |
| + web_resource_cache_(NULL), |
| + channel_(NULL) { |
| Init(); |
| } |
| PromoResourceService::~PromoResourceService() { } |
| void PromoResourceService::Init() { |
| - prefs_->RegisterDoublePref(prefs::kNTPCustomLogoStart, 0); |
| - prefs_->RegisterDoublePref(prefs::kNTPCustomLogoEnd, 0); |
| - prefs_->RegisterDoublePref(prefs::kNTPPromoStart, 0); |
| - prefs_->RegisterDoublePref(prefs::kNTPPromoEnd, 0); |
| - prefs_->RegisterStringPref(prefs::kNTPPromoLine, std::string()); |
| - prefs_->RegisterBooleanPref(prefs::kNTPPromoClosed, false); |
| - prefs_->RegisterIntegerPref(prefs::kNTPPromoGroup, -1); |
| - prefs_->RegisterIntegerPref(prefs::kNTPPromoBuild, |
| - DEV_BUILD | BETA_BUILD | STABLE_BUILD); |
| - prefs_->RegisterIntegerPref(prefs::kNTPPromoGroupTimeSlice, 0); |
| - |
| - // If the promo start is in the future, set a notification task to invalidate |
| - // the NTP cache at the time of the promo start. |
| - double promo_start = prefs_->GetDouble(prefs::kNTPPromoStart); |
| - double promo_end = prefs_->GetDouble(prefs::kNTPPromoEnd); |
| - ScheduleNotification(promo_start, promo_end); |
| + ScheduleNotificationOnInit(); |
| +} |
| + |
| +bool PromoResourceService::IsThisBuildTargeted(int builds_targeted) { |
| + std::string channel; |
| + if (channel_ != NULL) { |
| + channel = channel_; |
| + } else { |
| + base::ThreadRestrictions::ScopedAllowIO allow_io; |
| + channel = platform_util::GetVersionStringModifier(); |
|
Miranda Callahan
2011/04/13 14:29:29
did you want to cache the channel in channel_ here
jstritar
2011/04/13 19:52:27
Oh, yeah! Done.
|
| + } |
| + |
| + return IsBuildTargeted(channel, builds_targeted); |
| } |
| void PromoResourceService::Unpack(const DictionaryValue& parsed_json) { |
| UnpackLogoSignal(parsed_json); |
| UnpackPromoSignal(parsed_json); |
| + UnpackWebStoreSignal(parsed_json); |
| } |
| void PromoResourceService::ScheduleNotification(double promo_start, |
| @@ -109,6 +152,37 @@ void PromoResourceService::ScheduleNotification(double promo_start, |
| } |
| } |
| +void PromoResourceService::ScheduleNotificationOnInit() { |
| + std::string locale = g_browser_process->GetApplicationLocale(); |
| + if ((GetPromoServiceVersion() != kPromoServiceVersion) || |
| + (GetPromoLocale() != locale)) { |
| + // If the promo service has been upgraded or Chrome switched locales, |
| + // refresh the promos. |
| + PrefService* local_state = g_browser_process->local_state(); |
| + local_state->SetInteger(prefs::kNTPPromoVersion, kPromoServiceVersion); |
| + local_state->SetString(prefs::kNTPPromoLocale, locale); |
| + prefs_->ClearPref(prefs::kNTPPromoResourceCacheUpdate); |
| + AppsPromo::ClearPromo(); |
| + PostNotification(0); |
| + } else { |
| + // If the promo start is in the future, set a notification task to |
| + // invalidate the NTP cache at the time of the promo start. |
| + double promo_start = prefs_->GetDouble(prefs::kNTPPromoStart); |
| + double promo_end = prefs_->GetDouble(prefs::kNTPPromoEnd); |
| + ScheduleNotification(promo_start, promo_end); |
| + } |
| +} |
| + |
| +int PromoResourceService::GetPromoServiceVersion() { |
| + PrefService* local_state = g_browser_process->local_state(); |
| + return local_state->GetInteger(prefs::kNTPPromoVersion); |
| +} |
| + |
| +std::string PromoResourceService::GetPromoLocale() { |
| + PrefService* local_state = g_browser_process->local_state(); |
| + return local_state->GetString(prefs::kNTPPromoLocale); |
| +} |
| + |
| void PromoResourceService::UnpackPromoSignal( |
| const DictionaryValue& parsed_json) { |
| DictionaryValue* topic_dict; |
| @@ -208,6 +282,68 @@ void PromoResourceService::UnpackPromoSignal( |
| } |
| } |
| +void PromoResourceService::UnpackWebStoreSignal( |
| + const DictionaryValue& parsed_json) { |
| + DictionaryValue* topic_dict; |
| + ListValue* answer_list; |
| + |
| + bool signal_found = false; |
| + std::string promo_id = ""; |
| + std::string promo_header = ""; |
| + std::string promo_button = ""; |
| + std::string promo_link = ""; |
| + std::string promo_expire = ""; |
| + std::string promo_builds = ""; |
| + int target_builds; |
| + |
| + if (!parsed_json.GetDictionary("topic", &topic_dict) || |
| + !topic_dict->GetList("answers", &answer_list)) |
| + return; |
| + |
| + for (ListValue::const_iterator tip_iter = answer_list->begin(); |
|
Miranda Callahan
2011/04/13 14:29:29
can you change the name from the atavistic "tip_it
jstritar
2011/04/13 19:52:27
Done. I changed them to "answer_iter". Another opt
|
| + tip_iter != answer_list->end(); ++tip_iter) { |
| + if (!(*tip_iter)->IsType(Value::TYPE_DICTIONARY)) |
| + continue; |
| + DictionaryValue* a_dic = |
| + static_cast<DictionaryValue*>(*tip_iter); |
| + std::string promo_signal; |
| + if (!a_dic->GetString("name", &promo_signal) || |
| + promo_signal != "webstore_promo") |
| + continue; |
| + |
| + if (!a_dic->GetString(kAnswerIdProperty, &promo_id) || |
| + !a_dic->GetString(kWebStoreHeaderProperty, &promo_header) || |
| + !a_dic->GetString(kWebStoreButtonProperty, &promo_button) || |
| + !a_dic->GetString(kWebStoreLinkProperty, &promo_link) || |
| + !a_dic->GetString(kWebStoreExpireProperty, &promo_expire) || |
| + !a_dic->GetString(kWebStoreBuildsProperty, &promo_builds)) |
| + continue; |
| + |
| + if (!base::StringToInt(promo_builds, &target_builds)) |
| + continue; |
| + |
| + if (IsThisBuildTargeted(target_builds)) { |
| + // Store the first web store promo that targets the current build. |
| + AppsPromo::SetPromo( |
| + promo_id, promo_header, promo_button, GURL(promo_link), promo_expire); |
| + signal_found = true; |
| + break; |
| + } |
| + } |
| + |
| + if (!signal_found) { |
| + // If no web store promos target this build, then clear all the prefs. |
| + AppsPromo::ClearPromo(); |
| + } |
| + |
| + NotificationService::current()->Notify( |
| + NotificationType::WEB_STORE_PROMO_LOADED, |
| + Source<PromoResourceService>(this), |
| + NotificationService::NoDetails()); |
| + |
| + return; |
| +} |
| + |
| void PromoResourceService::UnpackLogoSignal( |
| const DictionaryValue& parsed_json) { |
| DictionaryValue* topic_dict; |
| @@ -290,27 +426,16 @@ bool CanShowPromo(Profile* profile) { |
| sync_ui_util::GetStatus( |
| profile->GetProfileSyncService()) == sync_ui_util::SYNCED); |
| - // GetVersionStringModifier hits the registry. See http://crbug.com/70898. |
| - base::ThreadRestrictions::ScopedAllowIO allow_io; |
| - const std::string channel = platform_util::GetVersionStringModifier(); |
| bool is_promo_build = false; |
| if (prefs->HasPrefPath(prefs::kNTPPromoBuild)) { |
| - int builds_allowed = prefs->GetInteger(prefs::kNTPPromoBuild); |
| - if (builds_allowed == NO_BUILD) |
| - return false; |
| - if (channel == "dev" || channel == "dev-m") { |
| - is_promo_build = (DEV_BUILD & builds_allowed) != 0; |
| - } else if (channel == "beta" || channel == "beta-m") { |
| - is_promo_build = (BETA_BUILD & builds_allowed) != 0; |
| - } else if (channel == "" || channel == "m") { |
| - is_promo_build = (STABLE_BUILD & builds_allowed) != 0; |
| - } else { |
| - is_promo_build = false; |
| - } |
| + // GetVersionStringModifier hits the registry. See http://crbug.com/70898. |
| + base::ThreadRestrictions::ScopedAllowIO allow_io; |
| + const std::string channel = platform_util::GetVersionStringModifier(); |
| + is_promo_build = PromoResourceService::IsBuildTargeted( |
| + channel, prefs->GetInteger(prefs::kNTPPromoBuild)); |
| } |
| return !promo_closed && !is_synced && is_promo_build; |
| } |
| } // namespace PromoResourceServiceUtil |
| - |