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

Side by Side Diff: chrome/browser/web_resource/promo_resource_service.cc

Issue 7719013: PromoResourceService fixes for 835 (Closed) Base URL: svn://svn.chromium.org/chrome/branches/835/src/
Patch Set: reset group on new promo, which triggers on promo_end change Created 9 years, 4 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/web_resource/promo_resource_service.h" 5 #include "chrome/browser/web_resource/promo_resource_service.h"
6 6
7 #include "base/string_number_conversions.h" 7 #include "base/string_number_conversions.h"
8 #include "base/threading/thread_restrictions.h" 8 #include "base/threading/thread_restrictions.h"
9 #include "base/time.h" 9 #include "base/time.h"
10 #include "base/values.h" 10 #include "base/values.h"
(...skipping 13 matching lines...) Expand all
24 24
25 // Delay on first fetch so we don't interfere with startup. 25 // Delay on first fetch so we don't interfere with startup.
26 static const int kStartResourceFetchDelay = 5000; 26 static const int kStartResourceFetchDelay = 5000;
27 27
28 // Delay between calls to update the cache (48 hours). 28 // Delay between calls to update the cache (48 hours).
29 static const int kCacheUpdateDelay = 48 * 60 * 60 * 1000; 29 static const int kCacheUpdateDelay = 48 * 60 * 60 * 1000;
30 30
31 // Users are randomly assigned to one of kNTPPromoGroupSize buckets, in order 31 // Users are randomly assigned to one of kNTPPromoGroupSize buckets, in order
32 // to be able to roll out promos slowly, or display different promos to 32 // to be able to roll out promos slowly, or display different promos to
33 // different groups. 33 // different groups.
34 static const int kNTPPromoGroupSize = 16; 34 static const int kNTPPromoGroupSize = 100;
35 35
36 // Maximum number of hours for each time slice (4 weeks). 36 // Maximum number of hours for each time slice (4 weeks).
37 static const int kMaxTimeSliceHours = 24 * 7 * 4; 37 static const int kMaxTimeSliceHours = 24 * 7 * 4;
38 38
39 // The version of the service (used to expire the cache when upgrading Chrome 39 // The version of the service (used to expire the cache when upgrading Chrome
40 // to versions with different types of promos). 40 // to versions with different types of promos).
41 static const int kPromoServiceVersion = 2; 41 static const int kPromoServiceVersion = 2;
42 42
43 // Properties used by the server. 43 // Properties used by the server.
44 static const char kAnswerIdProperty[] = "answer_id"; 44 static const char kAnswerIdProperty[] = "answer_id";
(...skipping 29 matching lines...) Expand all
74 prefs->RegisterDoublePref(prefs::kNTPPromoEnd, 74 prefs->RegisterDoublePref(prefs::kNTPPromoEnd,
75 0, 75 0,
76 PrefService::UNSYNCABLE_PREF); 76 PrefService::UNSYNCABLE_PREF);
77 prefs->RegisterStringPref(prefs::kNTPPromoLine, 77 prefs->RegisterStringPref(prefs::kNTPPromoLine,
78 std::string(), 78 std::string(),
79 PrefService::UNSYNCABLE_PREF); 79 PrefService::UNSYNCABLE_PREF);
80 prefs->RegisterBooleanPref(prefs::kNTPPromoClosed, 80 prefs->RegisterBooleanPref(prefs::kNTPPromoClosed,
81 false, 81 false,
82 PrefService::UNSYNCABLE_PREF); 82 PrefService::UNSYNCABLE_PREF);
83 prefs->RegisterIntegerPref(prefs::kNTPPromoGroup, 83 prefs->RegisterIntegerPref(prefs::kNTPPromoGroup,
84 -1, 84 0,
85 PrefService::UNSYNCABLE_PREF);
86 prefs->RegisterIntegerPref(prefs::kNTPPromoGroupMax,
87 0,
85 PrefService::UNSYNCABLE_PREF); 88 PrefService::UNSYNCABLE_PREF);
86 prefs->RegisterIntegerPref( 89 prefs->RegisterIntegerPref(
87 prefs::kNTPPromoBuild, 90 prefs::kNTPPromoBuild,
88 CANARY_BUILD | DEV_BUILD | BETA_BUILD | STABLE_BUILD, 91 CANARY_BUILD | DEV_BUILD | BETA_BUILD | STABLE_BUILD,
89 PrefService::UNSYNCABLE_PREF); 92 PrefService::UNSYNCABLE_PREF);
90 prefs->RegisterIntegerPref(prefs::kNTPPromoGroupTimeSlice, 93 prefs->RegisterIntegerPref(prefs::kNTPPromoGroupTimeSlice,
91 0, 94 0,
92 PrefService::UNSYNCABLE_PREF); 95 PrefService::UNSYNCABLE_PREF);
93 } 96 }
94 97
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 } 202 }
200 203
201 void PromoResourceService::UnpackPromoSignal( 204 void PromoResourceService::UnpackPromoSignal(
202 const DictionaryValue& parsed_json) { 205 const DictionaryValue& parsed_json) {
203 DictionaryValue* topic_dict; 206 DictionaryValue* topic_dict;
204 ListValue* answer_list; 207 ListValue* answer_list;
205 double old_promo_start = 0; 208 double old_promo_start = 0;
206 double old_promo_end = 0; 209 double old_promo_end = 0;
207 double promo_start = 0; 210 double promo_start = 0;
208 double promo_end = 0; 211 double promo_end = 0;
212 int time_slice_hrs = 0;
209 213
210 // Check for preexisting start and end values. 214 // Check for preexisting start and end values.
211 if (prefs_->HasPrefPath(prefs::kNTPPromoStart) && 215 if (prefs_->HasPrefPath(prefs::kNTPPromoStart) &&
212 prefs_->HasPrefPath(prefs::kNTPPromoEnd)) { 216 prefs_->HasPrefPath(prefs::kNTPPromoEnd)) {
213 old_promo_start = prefs_->GetDouble(prefs::kNTPPromoStart); 217 old_promo_start = prefs_->GetDouble(prefs::kNTPPromoStart);
214 old_promo_end = prefs_->GetDouble(prefs::kNTPPromoEnd); 218 old_promo_end = prefs_->GetDouble(prefs::kNTPPromoEnd);
215 } 219 }
216 220
217 // Check for newly received start and end values. 221 // Check for newly received start and end values.
218 if (parsed_json.GetDictionary("topic", &topic_dict)) { 222 if (parsed_json.GetDictionary("topic", &topic_dict)) {
219 if (topic_dict->GetList("answers", &answer_list)) { 223 if (topic_dict->GetList("answers", &answer_list)) {
220 std::string promo_start_string = ""; 224 std::string promo_start_string = "";
221 std::string promo_end_string = ""; 225 std::string promo_end_string = "";
222 std::string promo_string = ""; 226 std::string promo_string = "";
223 std::string promo_build = ""; 227 std::string promo_build = "";
224 int promo_build_type = 0; 228 int promo_build_type = 0;
225 int time_slice_hrs = 0; 229 int max_group = 0;
226 for (ListValue::const_iterator answer_iter = answer_list->begin(); 230 for (ListValue::const_iterator answer_iter = answer_list->begin();
227 answer_iter != answer_list->end(); ++answer_iter) { 231 answer_iter != answer_list->end(); ++answer_iter) {
228 if (!(*answer_iter)->IsType(Value::TYPE_DICTIONARY)) 232 if (!(*answer_iter)->IsType(Value::TYPE_DICTIONARY))
229 continue; 233 continue;
230 DictionaryValue* a_dic = 234 DictionaryValue* a_dic =
231 static_cast<DictionaryValue*>(*answer_iter); 235 static_cast<DictionaryValue*>(*answer_iter);
232 std::string promo_signal; 236 std::string promo_signal;
233 if (a_dic->GetString("name", &promo_signal)) { 237 if (a_dic->GetString("name", &promo_signal)) {
234 if (promo_signal == "promo_start") { 238 if (promo_signal == "promo_start") {
235 a_dic->GetString("question", &promo_build); 239 a_dic->GetString("question", &promo_build);
236 size_t split = promo_build.find(":"); 240 size_t split = promo_build.find(':');
241 size_t split2 = promo_build.rfind(':');
237 if (split != std::string::npos && 242 if (split != std::string::npos &&
243 split2 != std::string::npos &&
244 split != split2 &&
238 base::StringToInt(promo_build.substr(0, split), 245 base::StringToInt(promo_build.substr(0, split),
239 &promo_build_type) && 246 &promo_build_type) &&
240 base::StringToInt(promo_build.substr(split+1), 247 base::StringToInt(promo_build.substr(split + 1,
248 split2 - split - 1),
241 &time_slice_hrs) && 249 &time_slice_hrs) &&
250 base::StringToInt(promo_build.substr(split2 + 1),
251 &max_group) &&
242 promo_build_type >= 0 && 252 promo_build_type >= 0 &&
243 promo_build_type <= (DEV_BUILD | BETA_BUILD | STABLE_BUILD) && 253 promo_build_type <= (DEV_BUILD | BETA_BUILD | STABLE_BUILD) &&
244 time_slice_hrs >= 0 && 254 time_slice_hrs >= 0 &&
245 time_slice_hrs <= kMaxTimeSliceHours) { 255 time_slice_hrs <= kMaxTimeSliceHours &&
256 max_group >= 0 &&
257 max_group <= kNTPPromoGroupSize) {
246 prefs_->SetInteger(prefs::kNTPPromoBuild, promo_build_type); 258 prefs_->SetInteger(prefs::kNTPPromoBuild, promo_build_type);
247 prefs_->SetInteger(prefs::kNTPPromoGroupTimeSlice, 259 prefs_->SetInteger(prefs::kNTPPromoGroupTimeSlice,
248 time_slice_hrs); 260 time_slice_hrs);
261 prefs_->SetInteger(prefs::kNTPPromoGroupMax, max_group);
249 } else { 262 } else {
250 // If no time data or bad time data are set, do not show promo. 263 // If no time data or bad time data are set, do not show promo.
251 prefs_->SetInteger(prefs::kNTPPromoBuild, NO_BUILD); 264 prefs_->SetInteger(prefs::kNTPPromoBuild, NO_BUILD);
252 prefs_->SetInteger(prefs::kNTPPromoGroupTimeSlice, 0); 265 prefs_->SetInteger(prefs::kNTPPromoGroupTimeSlice, 0);
266 prefs_->SetInteger(prefs::kNTPPromoGroupMax, 0);
253 } 267 }
254 a_dic->GetString("inproduct", &promo_start_string); 268 a_dic->GetString("inproduct", &promo_start_string);
255 a_dic->GetString("tooltip", &promo_string); 269 a_dic->GetString("tooltip", &promo_string);
256 prefs_->SetString(prefs::kNTPPromoLine, promo_string); 270 prefs_->SetString(prefs::kNTPPromoLine, promo_string);
257 srand(static_cast<uint32>(time(NULL)));
258 prefs_->SetInteger(prefs::kNTPPromoGroup,
259 rand() % kNTPPromoGroupSize);
260 } else if (promo_signal == "promo_end") { 271 } else if (promo_signal == "promo_end") {
261 a_dic->GetString("inproduct", &promo_end_string); 272 a_dic->GetString("inproduct", &promo_end_string);
262 } 273 }
263 } 274 }
264 } 275 }
265 if (!promo_start_string.empty() && 276 if (!promo_start_string.empty() &&
266 promo_start_string.length() > 0 && 277 promo_start_string.length() > 0 &&
267 !promo_end_string.empty() && 278 !promo_end_string.empty() &&
268 promo_end_string.length() > 0) { 279 promo_end_string.length() > 0) {
269 base::Time start_time; 280 base::Time start_time;
270 base::Time end_time; 281 base::Time end_time;
271 if (base::Time::FromString( 282 if (base::Time::FromString(
272 ASCIIToWide(promo_start_string).c_str(), &start_time) && 283 ASCIIToWide(promo_start_string).c_str(), &start_time) &&
273 base::Time::FromString( 284 base::Time::FromString(
274 ASCIIToWide(promo_end_string).c_str(), &end_time)) { 285 ASCIIToWide(promo_end_string).c_str(), &end_time)) {
275 // Add group time slice, adjusted from hours to seconds. 286 promo_start = start_time.ToDoubleT();
276 promo_start = start_time.ToDoubleT() +
277 (prefs_->FindPreference(prefs::kNTPPromoGroup) ?
278 prefs_->GetInteger(prefs::kNTPPromoGroup) *
279 time_slice_hrs * 60 * 60 : 0);
280 promo_end = end_time.ToDoubleT(); 287 promo_end = end_time.ToDoubleT();
281 } 288 }
282 } 289 }
283 } 290 }
284 } 291 }
285 292
286 // If start or end times have changed, trigger a new web resource 293 // If end time has changed, trigger a new web resource
287 // notification, so that the logo on the NTP is updated. This check is 294 // notification, so that the logo on the NTP is updated. This check is
288 // outside the reading of the web resource data, because the absence of 295 // outside the reading of the web resource data, because the absence of
289 // dates counts as a triggering change if there were dates before. 296 // dates counts as a triggering change if there were dates before.
290 // Also reset the promo closed preference, to signal a new promo. 297 // Also reset the promo closed preference, to signal a new promo.
291 if (!(old_promo_start == promo_start) || 298 if (!(old_promo_end == promo_end)) {
292 !(old_promo_end == promo_end)) { 299 srand(static_cast<uint32>(time(NULL)));
300 int promo_group = rand() % kNTPPromoGroupSize;
301 prefs_->SetInteger(prefs::kNTPPromoGroup, promo_group);
302
303 // Add group time slice, adjusted from hours to seconds.
304 promo_start += promo_group * time_slice_hrs * 60 * 60;
293 prefs_->SetDouble(prefs::kNTPPromoStart, promo_start); 305 prefs_->SetDouble(prefs::kNTPPromoStart, promo_start);
294 prefs_->SetDouble(prefs::kNTPPromoEnd, promo_end); 306 prefs_->SetDouble(prefs::kNTPPromoEnd, promo_end);
295 prefs_->SetBoolean(prefs::kNTPPromoClosed, false); 307 prefs_->SetBoolean(prefs::kNTPPromoClosed, false);
296 ScheduleNotification(promo_start, promo_end); 308 ScheduleNotification(promo_start, promo_end);
297 } 309 }
298 } 310 }
299 311
300 void PromoResourceService::UnpackWebStoreSignal( 312 void PromoResourceService::UnpackWebStoreSignal(
301 const DictionaryValue& parsed_json) { 313 const DictionaryValue& parsed_json) {
302 DictionaryValue* topic_dict; 314 DictionaryValue* topic_dict;
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 } 469 }
458 470
459 namespace PromoResourceServiceUtil { 471 namespace PromoResourceServiceUtil {
460 472
461 bool CanShowPromo(Profile* profile) { 473 bool CanShowPromo(Profile* profile) {
462 bool promo_closed = false; 474 bool promo_closed = false;
463 PrefService* prefs = profile->GetPrefs(); 475 PrefService* prefs = profile->GetPrefs();
464 if (prefs->HasPrefPath(prefs::kNTPPromoClosed)) 476 if (prefs->HasPrefPath(prefs::kNTPPromoClosed))
465 promo_closed = prefs->GetBoolean(prefs::kNTPPromoClosed); 477 promo_closed = prefs->GetBoolean(prefs::kNTPPromoClosed);
466 478
467 // Only show if not synced. 479 bool is_valid_group = prefs->HasPrefPath(prefs::kNTPPromoGroup) &&
468 bool is_synced = 480 prefs->HasPrefPath(prefs::kNTPPromoGroupMax) &&
469 (profile->HasProfileSyncService() && 481 (prefs->GetInteger(prefs::kNTPPromoGroup) <
470 sync_ui_util::GetStatus( 482 prefs->GetInteger(prefs::kNTPPromoGroupMax));
471 profile->GetProfileSyncService()) == sync_ui_util::SYNCED);
472 483
473 bool is_promo_build = false; 484 bool is_promo_build = false;
474 if (prefs->HasPrefPath(prefs::kNTPPromoBuild)) { 485 if (prefs->HasPrefPath(prefs::kNTPPromoBuild)) {
475 // GetChannel hits the registry on Windows. See http://crbug.com/70898. 486 // GetChannel hits the registry on Windows. See http://crbug.com/70898.
476 base::ThreadRestrictions::ScopedAllowIO allow_io; 487 base::ThreadRestrictions::ScopedAllowIO allow_io;
477 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); 488 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
478 is_promo_build = PromoResourceService::IsBuildTargeted( 489 is_promo_build = PromoResourceService::IsBuildTargeted(
479 channel, prefs->GetInteger(prefs::kNTPPromoBuild)); 490 channel, prefs->GetInteger(prefs::kNTPPromoBuild));
480 } 491 }
481 492
482 return !promo_closed && !is_synced && is_promo_build; 493 return !promo_closed && is_valid_group && is_promo_build;
jstritar 2011/08/24 19:41:48 It might be good to test that CanShowPromo is fals
483 } 494 }
484 495
485 } // namespace PromoResourceServiceUtil 496 } // namespace PromoResourceServiceUtil
OLDNEW
« no previous file with comments | « chrome/browser/resources/new_tab.js ('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