OLD | NEW |
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" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 const char kPrefPromoText[] = "text"; | 42 const char kPrefPromoText[] = "text"; |
43 const char kPrefPromoPayload[] = "payload"; | 43 const char kPrefPromoPayload[] = "payload"; |
44 const char kPrefPromoStart[] = "start"; | 44 const char kPrefPromoStart[] = "start"; |
45 const char kPrefPromoEnd[] = "end"; | 45 const char kPrefPromoEnd[] = "end"; |
46 const char kPrefPromoNumGroups[] = "num_groups"; | 46 const char kPrefPromoNumGroups[] = "num_groups"; |
47 const char kPrefPromoSegment[] = "segment"; | 47 const char kPrefPromoSegment[] = "segment"; |
48 const char kPrefPromoIncrement[] = "increment"; | 48 const char kPrefPromoIncrement[] = "increment"; |
49 const char kPrefPromoIncrementFrequency[] = "increment_frequency"; | 49 const char kPrefPromoIncrementFrequency[] = "increment_frequency"; |
50 const char kPrefPromoIncrementMax[] = "increment_max"; | 50 const char kPrefPromoIncrementMax[] = "increment_max"; |
51 const char kPrefPromoMaxViews[] = "max_views"; | 51 const char kPrefPromoMaxViews[] = "max_views"; |
| 52 const char kPrefPromoMaxSeconds[] = "max_seconds"; |
| 53 const char kPrefPromoFirstViewTime[] = "first_view_time"; |
52 const char kPrefPromoGroup[] = "group"; | 54 const char kPrefPromoGroup[] = "group"; |
53 const char kPrefPromoViews[] = "views"; | 55 const char kPrefPromoViews[] = "views"; |
54 const char kPrefPromoClosed[] = "closed"; | 56 const char kPrefPromoClosed[] = "closed"; |
55 | 57 |
56 // Returns a string suitable for the Promo Server URL 'osname' value. | 58 // Returns a string suitable for the Promo Server URL 'osname' value. |
57 std::string PlatformString() { | 59 std::string PlatformString() { |
58 #if defined(OS_WIN) | 60 #if defined(OS_WIN) |
59 return "win"; | 61 return "win"; |
60 #elif defined(OS_ANDROID) | 62 #elif defined(OS_ANDROID) |
61 ui::DeviceFormFactor form_factor = ui::GetDeviceFormFactor(); | 63 ui::DeviceFormFactor form_factor = ui::GetDeviceFormFactor(); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 promo_type_(NO_PROMO), | 194 promo_type_(NO_PROMO), |
193 promo_payload_(new base::DictionaryValue()), | 195 promo_payload_(new base::DictionaryValue()), |
194 start_(0.0), | 196 start_(0.0), |
195 end_(0.0), | 197 end_(0.0), |
196 num_groups_(kDefaultGroupSize), | 198 num_groups_(kDefaultGroupSize), |
197 initial_segment_(0), | 199 initial_segment_(0), |
198 increment_(1), | 200 increment_(1), |
199 time_slice_(0), | 201 time_slice_(0), |
200 max_group_(0), | 202 max_group_(0), |
201 max_views_(0), | 203 max_views_(0), |
| 204 max_seconds_(0), |
| 205 first_view_time_(0), |
202 group_(0), | 206 group_(0), |
203 views_(0), | 207 views_(0), |
204 closed_(false), | 208 closed_(false), |
205 new_notification_(false) { | 209 new_notification_(false) { |
206 DCHECK(prefs_); | 210 DCHECK(prefs_); |
207 } | 211 } |
208 | 212 |
209 NotificationPromo::~NotificationPromo() {} | 213 NotificationPromo::~NotificationPromo() {} |
210 | 214 |
211 void NotificationPromo::InitFromJson(const base::DictionaryValue& json, | 215 void NotificationPromo::InitFromJson(const base::DictionaryValue& json, |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 // if no |payload.promo_message_short| is specified, | 281 // if no |payload.promo_message_short| is specified, |
278 // the first string in |strings| is used. | 282 // the first string in |strings| is used. |
279 base::DictionaryValue::Iterator iter(*strings); | 283 base::DictionaryValue::Iterator iter(*strings); |
280 iter.value().GetAsString(&promo_text_); | 284 iter.value().GetAsString(&promo_text_); |
281 } | 285 } |
282 DVLOG(1) << "promo_text_=" << promo_text_; | 286 DVLOG(1) << "promo_text_=" << promo_text_; |
283 | 287 |
284 promo->GetInteger("max_views", &max_views_); | 288 promo->GetInteger("max_views", &max_views_); |
285 DVLOG(1) << "max_views_ " << max_views_; | 289 DVLOG(1) << "max_views_ " << max_views_; |
286 | 290 |
| 291 promo->GetInteger("max_seconds", &max_seconds_); |
| 292 DVLOG(1) << "max_seconds_ " << max_seconds_; |
| 293 |
287 CheckForNewNotification(); | 294 CheckForNewNotification(); |
288 } | 295 } |
289 | 296 |
290 void NotificationPromo::CheckForNewNotification() { | 297 void NotificationPromo::CheckForNewNotification() { |
291 NotificationPromo old_promo; | 298 NotificationPromo old_promo; |
292 old_promo.InitFromPrefs(promo_type_); | 299 old_promo.InitFromPrefs(promo_type_); |
293 const double old_start = old_promo.start_; | 300 const double old_start = old_promo.start_; |
294 const double old_end = old_promo.end_; | 301 const double old_end = old_promo.end_; |
295 const std::string old_promo_text = old_promo.promo_text_; | 302 const std::string old_promo_text = old_promo.promo_text_; |
296 | 303 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 ntp_promo->SetDouble(kPrefPromoStart, start_); | 341 ntp_promo->SetDouble(kPrefPromoStart, start_); |
335 ntp_promo->SetDouble(kPrefPromoEnd, end_); | 342 ntp_promo->SetDouble(kPrefPromoEnd, end_); |
336 | 343 |
337 ntp_promo->SetInteger(kPrefPromoNumGroups, num_groups_); | 344 ntp_promo->SetInteger(kPrefPromoNumGroups, num_groups_); |
338 ntp_promo->SetInteger(kPrefPromoSegment, initial_segment_); | 345 ntp_promo->SetInteger(kPrefPromoSegment, initial_segment_); |
339 ntp_promo->SetInteger(kPrefPromoIncrement, increment_); | 346 ntp_promo->SetInteger(kPrefPromoIncrement, increment_); |
340 ntp_promo->SetInteger(kPrefPromoIncrementFrequency, time_slice_); | 347 ntp_promo->SetInteger(kPrefPromoIncrementFrequency, time_slice_); |
341 ntp_promo->SetInteger(kPrefPromoIncrementMax, max_group_); | 348 ntp_promo->SetInteger(kPrefPromoIncrementMax, max_group_); |
342 | 349 |
343 ntp_promo->SetInteger(kPrefPromoMaxViews, max_views_); | 350 ntp_promo->SetInteger(kPrefPromoMaxViews, max_views_); |
| 351 ntp_promo->SetInteger(kPrefPromoMaxSeconds, max_seconds_); |
| 352 ntp_promo->SetDouble(kPrefPromoFirstViewTime, first_view_time_); |
344 | 353 |
345 ntp_promo->SetInteger(kPrefPromoGroup, group_); | 354 ntp_promo->SetInteger(kPrefPromoGroup, group_); |
346 ntp_promo->SetInteger(kPrefPromoViews, views_); | 355 ntp_promo->SetInteger(kPrefPromoViews, views_); |
347 ntp_promo->SetBoolean(kPrefPromoClosed, closed_); | 356 ntp_promo->SetBoolean(kPrefPromoClosed, closed_); |
348 | 357 |
349 base::ListValue* promo_list = new base::ListValue; | 358 base::ListValue* promo_list = new base::ListValue; |
350 promo_list->Set(0, ntp_promo); // Only support 1 promo for now. | 359 promo_list->Set(0, ntp_promo); // Only support 1 promo for now. |
351 | 360 |
352 base::DictionaryValue promo_dict; | 361 base::DictionaryValue promo_dict; |
353 promo_dict.MergeDictionary(prefs_->GetDictionary(kPrefPromoObject)); | 362 promo_dict.MergeDictionary(prefs_->GetDictionary(kPrefPromoObject)); |
(...skipping 27 matching lines...) Expand all Loading... |
381 ntp_promo->GetDouble(kPrefPromoStart, &start_); | 390 ntp_promo->GetDouble(kPrefPromoStart, &start_); |
382 ntp_promo->GetDouble(kPrefPromoEnd, &end_); | 391 ntp_promo->GetDouble(kPrefPromoEnd, &end_); |
383 | 392 |
384 ntp_promo->GetInteger(kPrefPromoNumGroups, &num_groups_); | 393 ntp_promo->GetInteger(kPrefPromoNumGroups, &num_groups_); |
385 ntp_promo->GetInteger(kPrefPromoSegment, &initial_segment_); | 394 ntp_promo->GetInteger(kPrefPromoSegment, &initial_segment_); |
386 ntp_promo->GetInteger(kPrefPromoIncrement, &increment_); | 395 ntp_promo->GetInteger(kPrefPromoIncrement, &increment_); |
387 ntp_promo->GetInteger(kPrefPromoIncrementFrequency, &time_slice_); | 396 ntp_promo->GetInteger(kPrefPromoIncrementFrequency, &time_slice_); |
388 ntp_promo->GetInteger(kPrefPromoIncrementMax, &max_group_); | 397 ntp_promo->GetInteger(kPrefPromoIncrementMax, &max_group_); |
389 | 398 |
390 ntp_promo->GetInteger(kPrefPromoMaxViews, &max_views_); | 399 ntp_promo->GetInteger(kPrefPromoMaxViews, &max_views_); |
| 400 ntp_promo->GetInteger(kPrefPromoMaxSeconds, &max_seconds_); |
| 401 ntp_promo->GetDouble(kPrefPromoFirstViewTime, &first_view_time_); |
391 | 402 |
392 ntp_promo->GetInteger(kPrefPromoGroup, &group_); | 403 ntp_promo->GetInteger(kPrefPromoGroup, &group_); |
393 ntp_promo->GetInteger(kPrefPromoViews, &views_); | 404 ntp_promo->GetInteger(kPrefPromoViews, &views_); |
394 ntp_promo->GetBoolean(kPrefPromoClosed, &closed_); | 405 ntp_promo->GetBoolean(kPrefPromoClosed, &closed_); |
395 } | 406 } |
396 | 407 |
397 bool NotificationPromo::CheckAppLauncher() const { | 408 bool NotificationPromo::CheckAppLauncher() const { |
398 #if !defined(ENABLE_APP_LIST) | 409 #if !defined(ENABLE_APP_LIST) |
399 return true; | 410 return true; |
400 #else | 411 #else |
401 bool is_app_launcher_promo = false; | 412 bool is_app_launcher_promo = false; |
402 if (!promo_payload_->GetBoolean("is_app_launcher_promo", | 413 if (!promo_payload_->GetBoolean("is_app_launcher_promo", |
403 &is_app_launcher_promo)) | 414 &is_app_launcher_promo)) |
404 return true; | 415 return true; |
405 return !is_app_launcher_promo || | 416 return !is_app_launcher_promo || |
406 !prefs_->GetBoolean(prefs::kAppLauncherIsEnabled); | 417 !prefs_->GetBoolean(prefs::kAppLauncherIsEnabled); |
407 #endif // !defined(ENABLE_APP_LIST) | 418 #endif // !defined(ENABLE_APP_LIST) |
408 } | 419 } |
409 | 420 |
410 bool NotificationPromo::CanShow() const { | 421 bool NotificationPromo::CanShow() const { |
411 return !closed_ && | 422 return !closed_ && |
412 !promo_text_.empty() && | 423 !promo_text_.empty() && |
413 !ExceedsMaxGroup() && | 424 !ExceedsMaxGroup() && |
414 !ExceedsMaxViews() && | 425 !ExceedsMaxViews() && |
| 426 !ExceedsMaxSeconds() && |
415 CheckAppLauncher() && | 427 CheckAppLauncher() && |
416 base::Time::FromDoubleT(StartTimeForGroup()) < base::Time::Now() && | 428 base::Time::FromDoubleT(StartTimeForGroup()) < base::Time::Now() && |
417 base::Time::FromDoubleT(EndTime()) > base::Time::Now(); | 429 base::Time::FromDoubleT(EndTime()) > base::Time::Now(); |
418 } | 430 } |
419 | 431 |
420 // static | 432 // static |
421 void NotificationPromo::HandleClosed(PromoType promo_type) { | 433 void NotificationPromo::HandleClosed(PromoType promo_type) { |
422 content::RecordAction(UserMetricsAction("NTPPromoClosed")); | 434 content::RecordAction(UserMetricsAction("NTPPromoClosed")); |
423 NotificationPromo promo; | 435 NotificationPromo promo; |
424 promo.InitFromPrefs(promo_type); | 436 promo.InitFromPrefs(promo_type); |
425 if (!promo.closed_) { | 437 if (!promo.closed_) { |
426 promo.closed_ = true; | 438 promo.closed_ = true; |
427 promo.WritePrefs(); | 439 promo.WritePrefs(); |
428 } | 440 } |
429 } | 441 } |
430 | 442 |
431 // static | 443 // static |
432 bool NotificationPromo::HandleViewed(PromoType promo_type) { | 444 bool NotificationPromo::HandleViewed(PromoType promo_type) { |
433 content::RecordAction(UserMetricsAction("NTPPromoShown")); | 445 content::RecordAction(UserMetricsAction("NTPPromoShown")); |
434 NotificationPromo promo; | 446 NotificationPromo promo; |
435 promo.InitFromPrefs(promo_type); | 447 promo.InitFromPrefs(promo_type); |
436 ++promo.views_; | 448 ++promo.views_; |
| 449 if (promo.first_view_time_ == 0) { |
| 450 promo.first_view_time_ = base::Time::Now().ToDoubleT(); |
| 451 } |
437 promo.WritePrefs(); | 452 promo.WritePrefs(); |
438 return promo.ExceedsMaxViews(); | 453 return promo.ExceedsMaxViews() || promo.ExceedsMaxSeconds(); |
439 } | 454 } |
440 | 455 |
441 bool NotificationPromo::ExceedsMaxGroup() const { | 456 bool NotificationPromo::ExceedsMaxGroup() const { |
442 return (max_group_ == 0) ? false : group_ >= max_group_; | 457 return (max_group_ == 0) ? false : group_ >= max_group_; |
443 } | 458 } |
444 | 459 |
445 bool NotificationPromo::ExceedsMaxViews() const { | 460 bool NotificationPromo::ExceedsMaxViews() const { |
446 return (max_views_ == 0) ? false : views_ >= max_views_; | 461 return (max_views_ == 0) ? false : views_ >= max_views_; |
447 } | 462 } |
448 | 463 |
| 464 bool NotificationPromo::ExceedsMaxSeconds() const { |
| 465 if (max_seconds_ == 0 || first_view_time_ == 0) |
| 466 return false; |
| 467 |
| 468 const base::Time last_view_time = base::Time::FromDoubleT(first_view_time_) + |
| 469 base::TimeDelta::FromSeconds(max_seconds_); |
| 470 return last_view_time < base::Time::Now(); |
| 471 } |
| 472 |
449 // static | 473 // static |
450 GURL NotificationPromo::PromoServerURL() { | 474 GURL NotificationPromo::PromoServerURL() { |
451 GURL url(promo_server_url); | 475 GURL url(promo_server_url); |
452 AppendQueryParameter(&url, "dist", ChannelString()); | 476 AppendQueryParameter(&url, "dist", ChannelString()); |
453 AppendQueryParameter(&url, "osname", PlatformString()); | 477 AppendQueryParameter(&url, "osname", PlatformString()); |
454 AppendQueryParameter(&url, "branding", chrome::VersionInfo().Version()); | 478 AppendQueryParameter(&url, "branding", chrome::VersionInfo().Version()); |
455 AppendQueryParameter(&url, "osver", base::SysInfo::OperatingSystemVersion()); | 479 AppendQueryParameter(&url, "osver", base::SysInfo::OperatingSystemVersion()); |
456 DVLOG(1) << "PromoServerURL=" << url.spec(); | 480 DVLOG(1) << "PromoServerURL=" << url.spec(); |
457 // Note that locale param is added by WebResourceService. | 481 // Note that locale param is added by WebResourceService. |
458 return url; | 482 return url; |
459 } | 483 } |
460 | 484 |
461 double NotificationPromo::StartTimeForGroup() const { | 485 double NotificationPromo::StartTimeForGroup() const { |
462 if (group_ < initial_segment_) | 486 if (group_ < initial_segment_) |
463 return start_; | 487 return start_; |
464 return start_ + | 488 return start_ + |
465 std::ceil(static_cast<float>(group_ - initial_segment_ + 1) / increment_) | 489 std::ceil(static_cast<float>(group_ - initial_segment_ + 1) / increment_) |
466 * time_slice_; | 490 * time_slice_; |
467 } | 491 } |
468 | 492 |
469 double NotificationPromo::EndTime() const { | 493 double NotificationPromo::EndTime() const { |
470 return end_; | 494 return end_; |
471 } | 495 } |
OLD | NEW |