Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6565)

Unified Diff: chrome/browser/web_resource/promo_resource_service.cc

Issue 8073011: Merge 101979 - promo_resource_service fixes/cleanup for promos. (Closed) Base URL: svn://svn.chromium.org/chrome/branches/874/src/
Patch Set: Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/web_resource/promo_resource_service.cc
===================================================================
--- chrome/browser/web_resource/promo_resource_service.cc (revision 103209)
+++ chrome/browser/web_resource/promo_resource_service.cc (working copy)
@@ -34,7 +34,7 @@
// Users are randomly assigned to one of kNTPPromoGroupSize buckets, in order
// to be able to roll out promos slowly, or display different promos to
// different groups.
-static const int kNTPPromoGroupSize = 16;
+static const int kNTPPromoGroupSize = 100;
// Maximum number of hours for each time slice (4 weeks).
static const int kMaxTimeSliceHours = 24 * 7 * 4;
@@ -50,6 +50,28 @@
static const char kWebStoreLinkProperty[] = "inproduct";
static const char kWebStoreExpireProperty[] = "tooltip";
+chrome::VersionInfo::Channel GetChannel() {
+ // GetChannel hits the registry on Windows. See http://crbug.com/70898.
+ base::ThreadRestrictions::ScopedAllowIO allow_io;
+ return chrome::VersionInfo::GetChannel();
+}
+
+int GetNextQuestionValue(const std::string& question,
+ size_t* index,
+ bool* err) {
+ if (*err)
+ return 0;
+
+ size_t new_index = question.find(':', *index);
+ // Note that substr correctly handles npos.
+ std::string fragment(question.substr(*index, new_index - *index));
+ *index = new_index + 1;
+
+ int value;
+ *err = !base::StringToInt(fragment, &value);
+ return value;
+}
+
const char* GetPromoResourceURL() {
std::string promo_server_url = CommandLine::ForCurrentProcess()->
GetSwitchValueASCII(switches::kPromoServerURL);
@@ -60,8 +82,7 @@
} // namespace
-// Server for dynamically loaded NTP HTML elements. TODO(mirandac): append
-// locale for future usage, when we're serving localizable strings.
+// Server for dynamically loaded NTP HTML elements.
const char* PromoResourceService::kDefaultPromoResourceServer =
"https://www.google.com/support/chrome/bin/topic/1142433/inproduct?hl=";
@@ -92,15 +113,18 @@
false,
PrefService::UNSYNCABLE_PREF);
prefs->RegisterIntegerPref(prefs::kNTPPromoGroup,
- -1,
+ 0,
PrefService::UNSYNCABLE_PREF);
prefs->RegisterIntegerPref(
prefs::kNTPPromoBuild,
- CANARY_BUILD | DEV_BUILD | BETA_BUILD | STABLE_BUILD,
+ ALL_BUILDS,
PrefService::UNSYNCABLE_PREF);
prefs->RegisterIntegerPref(prefs::kNTPPromoGroupTimeSlice,
0,
PrefService::UNSYNCABLE_PREF);
+ prefs->RegisterIntegerPref(prefs::kNTPPromoGroupMax,
+ 0,
+ PrefService::UNSYNCABLE_PREF);
}
// static
@@ -132,9 +156,8 @@
prefs::kNTPPromoResourceCacheUpdate,
kStartResourceFetchDelay,
kCacheUpdateDelay),
- profile_(profile),
- web_resource_cache_(NULL),
- channel_(chrome::VersionInfo::CHANNEL_UNKNOWN) {
+ profile_(profile),
+ channel_(chrome::VersionInfo::CHANNEL_UNKNOWN) {
Init();
}
@@ -145,18 +168,15 @@
}
bool PromoResourceService::IsThisBuildTargeted(int builds_targeted) {
- if (channel_ == chrome::VersionInfo::CHANNEL_UNKNOWN) {
- // GetChannel hits the registry on Windows. See http://crbug.com/70898.
- base::ThreadRestrictions::ScopedAllowIO allow_io;
- channel_ = chrome::VersionInfo::GetChannel();
- }
+ if (channel_ == chrome::VersionInfo::CHANNEL_UNKNOWN)
+ channel_ = GetChannel();
return IsBuildTargeted(channel_, builds_targeted);
}
void PromoResourceService::Unpack(const DictionaryValue& parsed_json) {
UnpackLogoSignal(parsed_json);
- UnpackPromoSignal(parsed_json);
+ UnpackNotificationSignal(parsed_json);
UnpackWebStoreSignal(parsed_json);
}
@@ -212,103 +232,203 @@
return local_state->GetString(prefs::kNTPPromoLocale);
}
-void PromoResourceService::UnpackPromoSignal(
+void PromoResourceService::UnpackNotificationSignal(
const DictionaryValue& parsed_json) {
+ // Check for newly received start and end values.
+ std::string promo_start_string, promo_end_string;
+
DictionaryValue* topic_dict;
- ListValue* answer_list;
- double old_promo_start = 0;
- double old_promo_end = 0;
- double promo_start = 0;
- double promo_end = 0;
-
- // Check for preexisting start and end values.
- if (prefs_->HasPrefPath(prefs::kNTPPromoStart) &&
- prefs_->HasPrefPath(prefs::kNTPPromoEnd)) {
- old_promo_start = prefs_->GetDouble(prefs::kNTPPromoStart);
- old_promo_end = prefs_->GetDouble(prefs::kNTPPromoEnd);
- }
-
- // Check for newly received start and end values.
if (parsed_json.GetDictionary("topic", &topic_dict)) {
+ ListValue* answer_list;
if (topic_dict->GetList("answers", &answer_list)) {
- std::string promo_start_string = "";
- std::string promo_end_string = "";
- std::string promo_string = "";
- std::string promo_build = "";
- int promo_build_type = 0;
- int time_slice_hrs = 0;
for (ListValue::const_iterator answer_iter = answer_list->begin();
answer_iter != answer_list->end(); ++answer_iter) {
if (!(*answer_iter)->IsType(Value::TYPE_DICTIONARY))
continue;
- DictionaryValue* a_dic =
- static_cast<DictionaryValue*>(*answer_iter);
- std::string promo_signal;
- if (a_dic->GetString("name", &promo_signal)) {
- if (promo_signal == "promo_start") {
- a_dic->GetString("question", &promo_build);
- size_t split = promo_build.find(":");
- if (split != std::string::npos &&
- base::StringToInt(promo_build.substr(0, split),
- &promo_build_type) &&
- base::StringToInt(promo_build.substr(split+1),
- &time_slice_hrs) &&
- promo_build_type >= 0 &&
- promo_build_type <= (DEV_BUILD | BETA_BUILD | STABLE_BUILD) &&
- time_slice_hrs >= 0 &&
- time_slice_hrs <= kMaxTimeSliceHours) {
- prefs_->SetInteger(prefs::kNTPPromoBuild, promo_build_type);
- prefs_->SetInteger(prefs::kNTPPromoGroupTimeSlice,
- time_slice_hrs);
- } else {
- // If no time data or bad time data are set, do not show promo.
- prefs_->SetInteger(prefs::kNTPPromoBuild, NO_BUILD);
- prefs_->SetInteger(prefs::kNTPPromoGroupTimeSlice, 0);
- }
- a_dic->GetString("inproduct", &promo_start_string);
- a_dic->GetString("tooltip", &promo_string);
- prefs_->SetString(prefs::kNTPPromoLine, promo_string);
- srand(static_cast<uint32>(time(NULL)));
- prefs_->SetInteger(prefs::kNTPPromoGroup,
- rand() % kNTPPromoGroupSize);
- } else if (promo_signal == "promo_end") {
- a_dic->GetString("inproduct", &promo_end_string);
- }
- }
+
+ ParseNotification(static_cast<DictionaryValue*>(*answer_iter),
+ &promo_start_string, &promo_end_string);
}
- if (!promo_start_string.empty() &&
- promo_start_string.length() > 0 &&
- !promo_end_string.empty() &&
- promo_end_string.length() > 0) {
- base::Time start_time;
- base::Time end_time;
- if (base::Time::FromString(promo_start_string.c_str(), &start_time) &&
- base::Time::FromString(promo_end_string.c_str(), &end_time)) {
- // Add group time slice, adjusted from hours to seconds.
- promo_start = start_time.ToDoubleT() +
- (prefs_->FindPreference(prefs::kNTPPromoGroup) ?
- prefs_->GetInteger(prefs::kNTPPromoGroup) *
- time_slice_hrs * 60 * 60 : 0);
- promo_end = end_time.ToDoubleT();
- }
- }
}
}
+ CheckForNewNotification(promo_start_string, promo_end_string);
+}
+
+void PromoResourceService::ParseNotification(
+ DictionaryValue* a_dic,
+ std::string* promo_start_string,
+ std::string* promo_end_string) {
+ std::string promo_signal;
+ if (a_dic->GetString("name", &promo_signal)) {
+ if (promo_signal == "promo_start") {
+ SetNotificationParams(a_dic);
+ SetNotificationLine(a_dic);
+
+ a_dic->GetString("inproduct", promo_start_string);
+ } else if (promo_signal == "promo_end") {
+ a_dic->GetString("inproduct", promo_end_string);
+ }
+ }
+}
+
+void PromoResourceService::SetNotificationParams(DictionaryValue* a_dic) {
+ std::string question;
+ a_dic->GetString("question", &question);
+
+ size_t index(0);
+ bool err(false);
+ int promo_build = GetNextQuestionValue(question, &index, &err);
+ int time_slice = GetNextQuestionValue(question, &index, &err);
+ int max_group = GetNextQuestionValue(question, &index, &err);
+
+ if (err ||
+ promo_build < 0 ||
+ promo_build > ALL_BUILDS ||
+ time_slice < 0 ||
+ time_slice > kMaxTimeSliceHours ||
+ max_group < 0 ||
+ max_group >= kNTPPromoGroupSize) {
+ // If values are not valid, do not show promo.
+ NOTREACHED() << "Invalid server data, question=" << question <<
+ ", build=" << promo_build <<
+ ", time_slice=" << time_slice <<
+ ", max_group=" << max_group;
+ promo_build = NO_BUILD;
+ time_slice = 0;
+ max_group = 0;
+ }
+
+ prefs_->SetInteger(prefs::kNTPPromoBuild, promo_build);
+ prefs_->SetInteger(prefs::kNTPPromoGroupTimeSlice, time_slice);
+ prefs_->SetInteger(prefs::kNTPPromoGroupMax, max_group);
+}
+
+void PromoResourceService::SetNotificationLine(DictionaryValue* a_dic) {
+ std::string promo_line;
+ a_dic->GetString("tooltip", &promo_line);
+ if (!promo_line.empty())
+ prefs_->SetString(prefs::kNTPPromoLine, promo_line);
+}
+
+void PromoResourceService::CheckForNewNotification(
+ const std::string& promo_start_string,
+ const std::string& promo_end_string) {
+ double promo_start = 0.0, promo_end = 0.0;
+ ParseNewNotificationTimes(promo_start_string, promo_end_string,
+ &promo_start, &promo_end);
+
+ double old_promo_start = 0.0, old_promo_end = 0.0;
+ GetCurrentNotificationTimes(&old_promo_start, &old_promo_end);
+
// If start or end times have changed, trigger a new web resource
// notification, so that the logo on the NTP is updated. This check is
// outside the reading of the web resource data, because the absence of
// dates counts as a triggering change if there were dates before.
- // Also reset the promo closed preference, to signal a new promo.
- if (!(old_promo_start == promo_start) ||
- !(old_promo_end == promo_end)) {
- prefs_->SetDouble(prefs::kNTPPromoStart, promo_start);
- prefs_->SetDouble(prefs::kNTPPromoEnd, promo_end);
- prefs_->SetBoolean(prefs::kNTPPromoClosed, false);
- ScheduleNotification(promo_start, promo_end);
+ // Also create new promo groups, and reset the promo closed preference,
+ // to signal a new promo.
+ if (old_promo_start != promo_start || old_promo_end != promo_end)
+ OnNewNotification(promo_start, promo_end);
+}
+
+void PromoResourceService::ParseNewNotificationTimes(
+ const std::string& promo_start_string,
+ const std::string& promo_end_string,
+ double* promo_start,
+ double* promo_end) {
+ *promo_start = *promo_end = 0.0;
+
+ if (promo_start_string.empty() && !promo_end_string.empty())
+ return;
+
+ base::Time start_time, end_time;
+ if (!base::Time::FromString(promo_start_string.c_str(), &start_time) ||
+ !base::Time::FromString(promo_end_string.c_str(), &end_time))
+ return;
+
+ *promo_start = start_time.ToDoubleT();
+ *promo_end = end_time.ToDoubleT();
+}
+
+void PromoResourceService::GetCurrentNotificationTimes(double* old_promo_start,
+ double* old_promo_end) {
+ *old_promo_start = *old_promo_end = 0.0;
+ if (prefs_->HasPrefPath(prefs::kNTPPromoStart) &&
+ prefs_->HasPrefPath(prefs::kNTPPromoEnd)) {
+ *old_promo_start = prefs_->GetDouble(prefs::kNTPPromoStart);
+ *old_promo_end = prefs_->GetDouble(prefs::kNTPPromoEnd);
}
}
+int PromoResourceService::ResetNotificationGroup() {
+ srand(static_cast<uint32>(time(NULL)));
+ const int promo_group = rand() % kNTPPromoGroupSize;
+ prefs_->SetInteger(prefs::kNTPPromoGroup, promo_group);
+ return promo_group;
+}
+
+// static
+double PromoResourceService::GetNotificationStartTime(PrefService* prefs) {
+ if (!prefs->HasPrefPath(prefs::kNTPPromoStart))
+ return 0.0;
+
+ const double promo_start = prefs->GetDouble(prefs::kNTPPromoStart);
+
+ if (!prefs->HasPrefPath(prefs::kNTPPromoGroup) ||
+ !prefs->HasPrefPath(prefs::kNTPPromoGroupTimeSlice))
+ return promo_start;
+
+ const int promo_group = prefs->GetInteger(prefs::kNTPPromoGroup);
+ const int time_slice = prefs->GetInteger(prefs::kNTPPromoGroupTimeSlice);
+ // Adjust promo_start using group time slice, adjusted from hours to seconds.
+ static const double kSecondsInHour = 60.0 * 60.0;
+ return promo_start + promo_group * time_slice * kSecondsInHour;
+}
+
+void PromoResourceService::OnNewNotification(double promo_start,
+ double promo_end) {
+ ResetNotificationGroup();
+
+ prefs_->SetBoolean(prefs::kNTPPromoClosed, false);
+
+ prefs_->SetDouble(prefs::kNTPPromoStart, promo_start);
+ prefs_->SetDouble(prefs::kNTPPromoEnd, promo_end);
+
+ ScheduleNotification(GetNotificationStartTime(prefs_), promo_end);
+}
+
+bool PromoResourceService::CanShowNotificationPromo(Profile* profile) {
+ PrefService* prefs = profile->GetPrefs();
+
+ // Check if promo has been closed by the user.
+ if (prefs->HasPrefPath(prefs::kNTPPromoClosed) &&
+ prefs->GetBoolean(prefs::kNTPPromoClosed))
+ return false;
+
+ // Check if our build is appropriate for this promo.
+ if (!prefs->HasPrefPath(prefs::kNTPPromoBuild) ||
+ !IsBuildTargeted(GetChannel(), prefs->GetInteger(prefs::kNTPPromoBuild)))
+ return false;
+
+ // Check if we are in the right group for this promo.
+ if (!prefs->FindPreference(prefs::kNTPPromoGroup) ||
+ !prefs->FindPreference(prefs::kNTPPromoGroupMax) ||
+ (prefs->GetInteger(prefs::kNTPPromoGroup) >=
+ prefs->GetInteger(prefs::kNTPPromoGroupMax)))
+ return false;
+
+ // Check if we are in the right time window for this promo.
+ if (!prefs->FindPreference(prefs::kNTPPromoStart) ||
+ !prefs->FindPreference(prefs::kNTPPromoEnd) ||
+ base::Time::FromDoubleT(GetNotificationStartTime(prefs)) >
+ base::Time::Now() ||
+ base::Time::FromDoubleT(prefs->GetDouble(prefs::kNTPPromoEnd)) <
+ base::Time::Now())
+ return false;
+
+ return prefs->HasPrefPath(prefs::kNTPPromoLine);
+}
+
void PromoResourceService::UnpackWebStoreSignal(
const DictionaryValue& parsed_json) {
DictionaryValue* topic_dict;
@@ -465,31 +585,3 @@
NotificationService::NoDetails());
}
}
-
-namespace PromoResourceServiceUtil {
-
-bool CanShowPromo(Profile* profile) {
- bool promo_closed = false;
- PrefService* prefs = profile->GetPrefs();
- if (prefs->HasPrefPath(prefs::kNTPPromoClosed))
- promo_closed = prefs->GetBoolean(prefs::kNTPPromoClosed);
-
- // Only show if not synced.
- bool is_synced =
- (profile->HasProfileSyncService() &&
- sync_ui_util::GetStatus(
- profile->GetProfileSyncService()) == sync_ui_util::SYNCED);
-
- bool is_promo_build = false;
- if (prefs->HasPrefPath(prefs::kNTPPromoBuild)) {
- // GetChannel hits the registry on Windows. See http://crbug.com/70898.
- base::ThreadRestrictions::ScopedAllowIO allow_io;
- chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
- is_promo_build = PromoResourceService::IsBuildTargeted(
- channel, prefs->GetInteger(prefs::kNTPPromoBuild));
- }
-
- return !promo_closed && !is_synced && is_promo_build;
-}
-
-} // namespace PromoResourceServiceUtil
« no previous file with comments | « chrome/browser/web_resource/promo_resource_service.h ('k') | chrome/browser/web_resource/promo_resource_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698