| 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 |