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

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

Issue 11689004: Move PromoResourceService from Profile to BrowserProcessImpl/local_state(). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: nits Created 7 years, 11 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/notification_promo.h" 5 #include "chrome/browser/web_resource/notification_promo.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/rand_util.h" 11 #include "base/rand_util.h"
12 #include "base/string_number_conversions.h" 12 #include "base/string_number_conversions.h"
13 #include "base/string_util.h" 13 #include "base/string_util.h"
14 #include "base/sys_info.h" 14 #include "base/sys_info.h"
15 #include "base/threading/thread_restrictions.h"
15 #include "base/time.h" 16 #include "base/time.h"
16 #include "base/values.h" 17 #include "base/values.h"
18 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/prefs/pref_service.h" 19 #include "chrome/browser/prefs/pref_service.h"
18 #include "chrome/browser/profiles/profile_impl.h" 20 #include "chrome/browser/prefs/pref_service_simple.h"
21 #include "chrome/browser/prefs/pref_service_syncable.h"
19 #include "chrome/browser/web_resource/promo_resource_service.h" 22 #include "chrome/browser/web_resource/promo_resource_service.h"
20 #include "chrome/common/chrome_version_info.h" 23 #include "chrome/common/chrome_version_info.h"
21 #include "chrome/common/net/url_util.h" 24 #include "chrome/common/net/url_util.h"
22 #include "chrome/common/pref_names.h" 25 #include "chrome/common/pref_names.h"
23 #include "content/public/browser/user_metrics.h" 26 #include "content/public/browser/user_metrics.h"
24 #include "googleurl/src/gurl.h" 27 #include "googleurl/src/gurl.h"
25 28
26 #if defined(OS_ANDROID) 29 #if defined(OS_ANDROID)
27 #include "base/command_line.h" 30 #include "base/command_line.h"
28 #include "chrome/common/chrome_switches.h" 31 #include "chrome/common/chrome_switches.h"
(...skipping 17 matching lines...) Expand all
46 const char kPrefPromoEnd[] = "end"; 49 const char kPrefPromoEnd[] = "end";
47 const char kPrefPromoNumGroups[] = "num_groups"; 50 const char kPrefPromoNumGroups[] = "num_groups";
48 const char kPrefPromoSegment[] = "segment"; 51 const char kPrefPromoSegment[] = "segment";
49 const char kPrefPromoIncrement[] = "increment"; 52 const char kPrefPromoIncrement[] = "increment";
50 const char kPrefPromoIncrementFrequency[] = "increment_frequency"; 53 const char kPrefPromoIncrementFrequency[] = "increment_frequency";
51 const char kPrefPromoIncrementMax[] = "increment_max"; 54 const char kPrefPromoIncrementMax[] = "increment_max";
52 const char kPrefPromoMaxViews[] = "max_views"; 55 const char kPrefPromoMaxViews[] = "max_views";
53 const char kPrefPromoGroup[] = "group"; 56 const char kPrefPromoGroup[] = "group";
54 const char kPrefPromoViews[] = "views"; 57 const char kPrefPromoViews[] = "views";
55 const char kPrefPromoClosed[] = "closed"; 58 const char kPrefPromoClosed[] = "closed";
56 const char kPrefPromoGPlusRequired[] = "gplus_required";
57 59
58 // Returns a string suitable for the Promo Server URL 'osname' value. 60 // Returns a string suitable for the Promo Server URL 'osname' value.
59 std::string PlatformString() { 61 std::string PlatformString() {
60 #if defined(OS_WIN) 62 #if defined(OS_WIN)
61 return "win"; 63 return "win";
62 #elif defined(OS_IOS) 64 #elif defined(OS_IOS)
63 // TODO(noyau): add iOS-specific implementation 65 // TODO(noyau): add iOS-specific implementation
64 const bool isTablet = false; 66 const bool isTablet = false;
65 return std::string("ios-") + (isTablet ? "tablet" : "phone"); 67 return std::string("ios-") + (isTablet ? "tablet" : "phone");
66 #elif defined(OS_MACOSX) 68 #elif defined(OS_MACOSX)
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 } 184 }
183 185
184 void AppendQueryParameter(GURL* url, 186 void AppendQueryParameter(GURL* url,
185 const std::string& param, 187 const std::string& param,
186 const std::string& value) { 188 const std::string& value) {
187 *url = chrome_common_net::AppendQueryParameter(*url, param, value); 189 *url = chrome_common_net::AppendQueryParameter(*url, param, value);
188 } 190 }
189 191
190 } // namespace 192 } // namespace
191 193
192 NotificationPromo::NotificationPromo(Profile* profile) 194 NotificationPromo::NotificationPromo()
193 : profile_(profile), 195 : prefs_(g_browser_process->local_state()),
Robert Sesek 2013/01/03 21:40:10 Can you dependency inject this, potentially allowi
Dan Beam 2013/01/03 22:47:38 I was doing that before but estade@ and I thought
194 prefs_(profile_->GetPrefs()),
195 promo_type_(NO_PROMO), 196 promo_type_(NO_PROMO),
196 promo_payload_(new base::DictionaryValue()), 197 promo_payload_(new base::DictionaryValue()),
197 start_(0.0), 198 start_(0.0),
198 end_(0.0), 199 end_(0.0),
199 num_groups_(kDefaultGroupSize), 200 num_groups_(kDefaultGroupSize),
200 initial_segment_(0), 201 initial_segment_(0),
201 increment_(1), 202 increment_(1),
202 time_slice_(0), 203 time_slice_(0),
203 max_group_(0), 204 max_group_(0),
204 max_views_(0), 205 max_views_(0),
205 group_(0), 206 group_(0),
206 views_(0), 207 views_(0),
207 closed_(false), 208 closed_(false),
208 gplus_required_(false),
209 new_notification_(false) { 209 new_notification_(false) {
210 DCHECK(profile);
211 DCHECK(prefs_); 210 DCHECK(prefs_);
212 } 211 }
213 212
214 NotificationPromo::~NotificationPromo() {} 213 NotificationPromo::~NotificationPromo() {}
215 214
216 void NotificationPromo::InitFromJson(const DictionaryValue& json, 215 void NotificationPromo::InitFromJson(const DictionaryValue& json,
217 PromoType promo_type) { 216 PromoType promo_type) {
218 promo_type_ = promo_type; 217 promo_type_ = promo_type;
219 const ListValue* promo_list = NULL; 218 const ListValue* promo_list = NULL;
220 DVLOG(1) << "InitFromJson " << PromoTypeToString(promo_type_); 219 DVLOG(1) << "InitFromJson " << PromoTypeToString(promo_type_);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 << ", max_group_ = " << max_group_; 263 << ", max_group_ = " << max_group_;
265 } 264 }
266 265
267 // Strings. 266 // Strings.
268 const DictionaryValue* strings = NULL; 267 const DictionaryValue* strings = NULL;
269 promo->GetDictionary("strings", &strings); 268 promo->GetDictionary("strings", &strings);
270 269
271 // Payload. 270 // Payload.
272 const DictionaryValue* payload = NULL; 271 const DictionaryValue* payload = NULL;
273 if (promo->GetDictionary("payload", &payload)) { 272 if (promo->GetDictionary("payload", &payload)) {
274 payload->GetBoolean("gplus_required", &gplus_required_);
275 DVLOG(1) << "gplus_required_ = " << gplus_required_;
276
277 base::Value* ppcopy = DeepCopyAndResolveStrings(payload, strings); 273 base::Value* ppcopy = DeepCopyAndResolveStrings(payload, strings);
278 DCHECK(ppcopy && ppcopy->IsType(base::Value::TYPE_DICTIONARY)); 274 DCHECK(ppcopy && ppcopy->IsType(base::Value::TYPE_DICTIONARY));
279 promo_payload_.reset(static_cast<base::DictionaryValue*>(ppcopy)); 275 promo_payload_.reset(static_cast<base::DictionaryValue*>(ppcopy));
280 } 276 }
281 277
282 if (!promo_payload_->GetString("promo_message_short", &promo_text_) && 278 if (!promo_payload_->GetString("promo_message_short", &promo_text_) &&
283 strings) { 279 strings) {
284 // For compatibility with the legacy desktop version, 280 // For compatibility with the legacy desktop version,
285 // if no |payload.promo_message_short| is specified, 281 // if no |payload.promo_message_short| is specified,
286 // the first string in |strings| is used. 282 // the first string in |strings| is used.
287 DictionaryValue::Iterator iter(*strings); 283 DictionaryValue::Iterator iter(*strings);
288 iter.value().GetAsString(&promo_text_); 284 iter.value().GetAsString(&promo_text_);
289 } 285 }
290 DVLOG(1) << "promo_text_=" << promo_text_; 286 DVLOG(1) << "promo_text_=" << promo_text_;
291 287
292 promo->GetInteger("max_views", &max_views_); 288 promo->GetInteger("max_views", &max_views_);
293 DVLOG(1) << "max_views_ " << max_views_; 289 DVLOG(1) << "max_views_ " << max_views_;
294 290
295 CheckForNewNotification(); 291 CheckForNewNotification();
296 } 292 }
297 293
298 void NotificationPromo::CheckForNewNotification() { 294 void NotificationPromo::CheckForNewNotification() {
299 NotificationPromo old_promo(profile_); 295 NotificationPromo old_promo(prefs_);
300 old_promo.InitFromPrefs(promo_type_); 296 old_promo.InitFromPrefs(promo_type_);
301 const double old_start = old_promo.start_; 297 const double old_start = old_promo.start_;
302 const double old_end = old_promo.end_; 298 const double old_end = old_promo.end_;
303 const std::string old_promo_text = old_promo.promo_text_; 299 const std::string old_promo_text = old_promo.promo_text_;
304 300
305 new_notification_ = 301 new_notification_ =
306 old_start != start_ || old_end != end_ || old_promo_text != promo_text_; 302 old_start != start_ || old_end != end_ || old_promo_text != promo_text_;
307 if (new_notification_) 303 if (new_notification_)
308 OnNewNotification(); 304 OnNewNotification();
309 } 305 }
310 306
311 void NotificationPromo::OnNewNotification() { 307 void NotificationPromo::OnNewNotification() {
312 DVLOG(1) << "OnNewNotification"; 308 DVLOG(1) << "OnNewNotification";
313 // Create a new promo group. 309 // Create a new promo group.
314 group_ = base::RandInt(0, num_groups_ - 1); 310 group_ = base::RandInt(0, num_groups_ - 1);
315 WritePrefs(); 311 WritePrefs();
316 } 312 }
317 313
318 // static 314 // static
315 void NotificationPromo::RegisterPrefs(PrefServiceSimple* local_state) {
316 local_state->RegisterDictionaryPref(kPrefPromoObject);
317 }
318
319 // static
319 void NotificationPromo::RegisterUserPrefs(PrefServiceSyncable* prefs) { 320 void NotificationPromo::RegisterUserPrefs(PrefServiceSyncable* prefs) {
321 // TODO(dbeam): Remove in M28 when we're reasonably sure all prefs are gone.
320 prefs->RegisterDictionaryPref(kPrefPromoObject, 322 prefs->RegisterDictionaryPref(kPrefPromoObject,
321 new base::DictionaryValue,
322 PrefServiceSyncable::UNSYNCABLE_PREF); 323 PrefServiceSyncable::UNSYNCABLE_PREF);
324 prefs->ClearPref(kPrefPromoObject);
323 } 325 }
324 326
325 void NotificationPromo::WritePrefs() { 327 void NotificationPromo::WritePrefs() {
326 base::DictionaryValue* ntp_promo = new base::DictionaryValue; 328 base::DictionaryValue* ntp_promo = new base::DictionaryValue;
327 ntp_promo->SetString(kPrefPromoText, promo_text_); 329 ntp_promo->SetString(kPrefPromoText, promo_text_);
328 ntp_promo->Set(kPrefPromoPayload, promo_payload_->DeepCopy()); 330 ntp_promo->Set(kPrefPromoPayload, promo_payload_->DeepCopy());
329 ntp_promo->SetDouble(kPrefPromoStart, start_); 331 ntp_promo->SetDouble(kPrefPromoStart, start_);
330 ntp_promo->SetDouble(kPrefPromoEnd, end_); 332 ntp_promo->SetDouble(kPrefPromoEnd, end_);
331 333
332 ntp_promo->SetInteger(kPrefPromoNumGroups, num_groups_); 334 ntp_promo->SetInteger(kPrefPromoNumGroups, num_groups_);
333 ntp_promo->SetInteger(kPrefPromoSegment, initial_segment_); 335 ntp_promo->SetInteger(kPrefPromoSegment, initial_segment_);
334 ntp_promo->SetInteger(kPrefPromoIncrement, increment_); 336 ntp_promo->SetInteger(kPrefPromoIncrement, increment_);
335 ntp_promo->SetInteger(kPrefPromoIncrementFrequency, time_slice_); 337 ntp_promo->SetInteger(kPrefPromoIncrementFrequency, time_slice_);
336 ntp_promo->SetInteger(kPrefPromoIncrementMax, max_group_); 338 ntp_promo->SetInteger(kPrefPromoIncrementMax, max_group_);
337 339
338 ntp_promo->SetInteger(kPrefPromoMaxViews, max_views_); 340 ntp_promo->SetInteger(kPrefPromoMaxViews, max_views_);
339 341
340 ntp_promo->SetInteger(kPrefPromoGroup, group_); 342 ntp_promo->SetInteger(kPrefPromoGroup, group_);
341 ntp_promo->SetInteger(kPrefPromoViews, views_); 343 ntp_promo->SetInteger(kPrefPromoViews, views_);
342 ntp_promo->SetBoolean(kPrefPromoClosed, closed_); 344 ntp_promo->SetBoolean(kPrefPromoClosed, closed_);
343 345
344 ntp_promo->SetBoolean(kPrefPromoGPlusRequired, gplus_required_);
345
346 base::ListValue* promo_list = new base::ListValue; 346 base::ListValue* promo_list = new base::ListValue;
347 promo_list->Set(0, ntp_promo); // Only support 1 promo for now. 347 promo_list->Set(0, ntp_promo); // Only support 1 promo for now.
348 348
349 base::DictionaryValue promo_dict; 349 base::DictionaryValue promo_dict;
350 promo_dict.MergeDictionary(prefs_->GetDictionary(kPrefPromoObject)); 350 promo_dict.MergeDictionary(prefs_->GetDictionary(kPrefPromoObject));
351 promo_dict.Set(PromoTypeToString(promo_type_), promo_list); 351 promo_dict.Set(PromoTypeToString(promo_type_), promo_list);
352 prefs_->Set(kPrefPromoObject, promo_dict); 352 prefs_->Set(kPrefPromoObject, promo_dict);
353 DVLOG(1) << "WritePrefs " << promo_dict; 353 DVLOG(1) << "WritePrefs " << promo_dict;
354 } 354 }
355 355
(...skipping 26 matching lines...) Expand all
382 ntp_promo->GetInteger(kPrefPromoSegment, &initial_segment_); 382 ntp_promo->GetInteger(kPrefPromoSegment, &initial_segment_);
383 ntp_promo->GetInteger(kPrefPromoIncrement, &increment_); 383 ntp_promo->GetInteger(kPrefPromoIncrement, &increment_);
384 ntp_promo->GetInteger(kPrefPromoIncrementFrequency, &time_slice_); 384 ntp_promo->GetInteger(kPrefPromoIncrementFrequency, &time_slice_);
385 ntp_promo->GetInteger(kPrefPromoIncrementMax, &max_group_); 385 ntp_promo->GetInteger(kPrefPromoIncrementMax, &max_group_);
386 386
387 ntp_promo->GetInteger(kPrefPromoMaxViews, &max_views_); 387 ntp_promo->GetInteger(kPrefPromoMaxViews, &max_views_);
388 388
389 ntp_promo->GetInteger(kPrefPromoGroup, &group_); 389 ntp_promo->GetInteger(kPrefPromoGroup, &group_);
390 ntp_promo->GetInteger(kPrefPromoViews, &views_); 390 ntp_promo->GetInteger(kPrefPromoViews, &views_);
391 ntp_promo->GetBoolean(kPrefPromoClosed, &closed_); 391 ntp_promo->GetBoolean(kPrefPromoClosed, &closed_);
392
393 ntp_promo->GetBoolean(kPrefPromoGPlusRequired, &gplus_required_);
394 } 392 }
395 393
396 bool NotificationPromo::CanShow() const { 394 bool NotificationPromo::CanShow() const {
397 return !closed_ && 395 return !closed_ &&
398 !promo_text_.empty() && 396 !promo_text_.empty() &&
399 !ExceedsMaxGroup() && 397 !ExceedsMaxGroup() &&
400 !ExceedsMaxViews() && 398 !ExceedsMaxViews() &&
401 base::Time::FromDoubleT(StartTimeForGroup()) < base::Time::Now() && 399 base::Time::FromDoubleT(StartTimeForGroup()) < base::Time::Now() &&
402 base::Time::FromDoubleT(EndTime()) > base::Time::Now() && 400 base::Time::FromDoubleT(EndTime()) > base::Time::Now();
403 IsGPlusRequired();
404 } 401 }
405 402
406 // static 403 // static
407 void NotificationPromo::HandleClosed(Profile* profile, PromoType promo_type) { 404 void NotificationPromo::HandleClosed(PromoType promo_type) {
408 content::RecordAction(UserMetricsAction("NTPPromoClosed")); 405 content::RecordAction(UserMetricsAction("NTPPromoClosed"));
409 NotificationPromo promo(profile); 406 NotificationPromo promo;
410 promo.InitFromPrefs(promo_type); 407 HandleClosedInternal(&promo, promo_type);
411 if (!promo.closed_) { 408 }
412 promo.closed_ = true; 409
413 promo.WritePrefs(); 410 // static
411 bool NotificationPromo::HandleViewed(PromoType promo_type) {
412 content::RecordAction(UserMetricsAction("NTPPromoShown"));
413 NotificationPromo promo;
414 return HandleViewedInternal(&promo, promo_type);
415 }
416
417 // static
418 void NotificationPromo::HandleClosedInternal(NotificationPromo* promo,
419 PromoType promo_type) {
420 promo->InitFromPrefs(promo_type);
421 if (!promo->closed_) {
422 promo->closed_ = true;
423 promo->WritePrefs();
414 } 424 }
415 } 425 }
416 426
417 // static 427 // static
418 bool NotificationPromo::HandleViewed(Profile* profile, PromoType promo_type) { 428 bool NotificationPromo::HandleViewedInternal(NotificationPromo* promo,
419 content::RecordAction(UserMetricsAction("NTPPromoShown")); 429 PromoType promo_type) {
420 NotificationPromo promo(profile); 430 promo->InitFromPrefs(promo_type);
421 promo.InitFromPrefs(promo_type); 431 ++promo->views_;
422 ++promo.views_; 432 promo->WritePrefs();
423 promo.WritePrefs(); 433 return promo->ExceedsMaxViews();
424 return promo.ExceedsMaxViews(); 434 }
435
436 // Testing constructor.
437 NotificationPromo::NotificationPromo(PrefService* prefs)
438 : prefs_(prefs),
439 promo_type_(NO_PROMO),
440 promo_payload_(new base::DictionaryValue()),
441 start_(0.0),
442 end_(0.0),
443 num_groups_(kDefaultGroupSize),
444 initial_segment_(0),
445 increment_(1),
446 time_slice_(0),
447 max_group_(0),
448 max_views_(0),
449 group_(0),
450 views_(0),
451 closed_(false),
452 new_notification_(false) {
453 DCHECK(prefs_);
454 }
455
456 // static
457 void NotificationPromo::HandleClosedForTesting(PrefService* prefs,
458 PromoType promo_type) {
459 NotificationPromo testing_promo(prefs);
460 HandleClosedInternal(&testing_promo, promo_type);
461 }
462
463 // static
464 bool NotificationPromo::HandleViewedForTesting(PrefService* prefs,
465 PromoType promo_type) {
466 NotificationPromo testing_promo(prefs);
467 return HandleViewedInternal(&testing_promo, promo_type);
425 } 468 }
426 469
427 bool NotificationPromo::ExceedsMaxGroup() const { 470 bool NotificationPromo::ExceedsMaxGroup() const {
428 return (max_group_ == 0) ? false : group_ >= max_group_; 471 return (max_group_ == 0) ? false : group_ >= max_group_;
429 } 472 }
430 473
431 bool NotificationPromo::ExceedsMaxViews() const { 474 bool NotificationPromo::ExceedsMaxViews() const {
432 return (max_views_ == 0) ? false : views_ >= max_views_; 475 return (max_views_ == 0) ? false : views_ >= max_views_;
433 } 476 }
434 477
435 bool NotificationPromo::IsGPlusRequired() const {
436 return !gplus_required_ || prefs_->GetBoolean(prefs::kIsGooglePlusUser);
437 }
438
439 // static 478 // static
440 GURL NotificationPromo::PromoServerURL() { 479 GURL NotificationPromo::PromoServerURL() {
441 GURL url(promo_server_url); 480 GURL url(promo_server_url);
442 AppendQueryParameter(&url, "dist", ChannelString()); 481 AppendQueryParameter(&url, "dist", ChannelString());
443 AppendQueryParameter(&url, "osname", PlatformString()); 482 AppendQueryParameter(&url, "osname", PlatformString());
444 AppendQueryParameter(&url, "branding", chrome::VersionInfo().Version()); 483 AppendQueryParameter(&url, "branding", chrome::VersionInfo().Version());
445 AppendQueryParameter(&url, "osver", base::SysInfo::OperatingSystemVersion()); 484 AppendQueryParameter(&url, "osver", base::SysInfo::OperatingSystemVersion());
446 DVLOG(1) << "PromoServerURL=" << url.spec(); 485 DVLOG(1) << "PromoServerURL=" << url.spec();
447 // Note that locale param is added by WebResourceService. 486 // Note that locale param is added by WebResourceService.
448 return url; 487 return url;
449 } 488 }
450 489
451 double NotificationPromo::StartTimeForGroup() const { 490 double NotificationPromo::StartTimeForGroup() const {
452 if (group_ < initial_segment_) 491 if (group_ < initial_segment_)
453 return start_; 492 return start_;
454 return start_ + 493 return start_ +
455 std::ceil(static_cast<float>(group_ - initial_segment_ + 1) / increment_) 494 std::ceil(static_cast<float>(group_ - initial_segment_ + 1) / increment_)
456 * time_slice_; 495 * time_slice_;
457 } 496 }
458 497
459 double NotificationPromo::EndTime() const { 498 double NotificationPromo::EndTime() const {
460 return end_; 499 return end_;
461 } 500 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698