| 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 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 return "dev"; | 98 return "dev"; |
| 99 case chrome::VersionInfo::CHANNEL_BETA: | 99 case chrome::VersionInfo::CHANNEL_BETA: |
| 100 return "beta"; | 100 return "beta"; |
| 101 case chrome::VersionInfo::CHANNEL_STABLE: | 101 case chrome::VersionInfo::CHANNEL_STABLE: |
| 102 return "stable"; | 102 return "stable"; |
| 103 default: | 103 default: |
| 104 return "none"; | 104 return "none"; |
| 105 } | 105 } |
| 106 } | 106 } |
| 107 | 107 |
| 108 struct PromoMapEntry { |
| 109 NotificationPromo::PromoType promo_type; |
| 110 const char* promo_type_str; |
| 111 }; |
| 112 |
| 113 const PromoMapEntry kPromoMap[] = { |
| 114 { NotificationPromo::NO_PROMO, "" }, |
| 115 { NotificationPromo::NTP_NOTIFICATION_PROMO, "ntp_notification_promo" }, |
| 116 { NotificationPromo::BUBBLE_PROMO, "bubble_promo" }, |
| 117 { NotificationPromo::MOBILE_NTP_SYNC_PROMO, "mobile_ntp_sync_promo" }, |
| 118 }; |
| 119 |
| 120 // Convert PromoType to appropriate string. |
| 121 const char* PromoTypeToString(NotificationPromo::PromoType promo_type) { |
| 122 for (size_t i = 0; i < arraysize(kPromoMap); ++i) { |
| 123 if (kPromoMap[i].promo_type == promo_type) |
| 124 return kPromoMap[i].promo_type_str; |
| 125 } |
| 126 NOTREACHED(); |
| 127 return ""; |
| 128 } |
| 129 |
| 108 // TODO(achuith): remove this in m23. | 130 // TODO(achuith): remove this in m23. |
| 109 void ClearDeprecatedPrefs(PrefService* prefs) { | 131 void ClearDeprecatedPrefs(PrefService* prefs) { |
| 110 prefs->RegisterStringPref(prefs::kNtpPromoLine, | 132 prefs->RegisterStringPref(prefs::kNtpPromoLine, |
| 111 std::string(), | 133 std::string(), |
| 112 PrefService::UNSYNCABLE_PREF); | 134 PrefService::UNSYNCABLE_PREF); |
| 113 prefs->ClearPref(prefs::kNtpPromoLine); | 135 prefs->ClearPref(prefs::kNtpPromoLine); |
| 114 #if defined(OS_ANDROID) | 136 #if defined(OS_ANDROID) |
| 115 prefs->RegisterStringPref(prefs::kNtpPromoLineLong, | 137 prefs->RegisterStringPref(prefs::kNtpPromoLineLong, |
| 116 std::string(), | 138 std::string(), |
| 117 PrefService::UNSYNCABLE_PREF); | 139 PrefService::UNSYNCABLE_PREF); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 prefs->ClearPref(prefs::kNtpPromoGroupMax); | 198 prefs->ClearPref(prefs::kNtpPromoGroupMax); |
| 177 prefs->ClearPref(prefs::kNtpPromoViewsMax); | 199 prefs->ClearPref(prefs::kNtpPromoViewsMax); |
| 178 prefs->ClearPref(prefs::kNtpPromoGroup); | 200 prefs->ClearPref(prefs::kNtpPromoGroup); |
| 179 prefs->ClearPref(prefs::kNtpPromoViews); | 201 prefs->ClearPref(prefs::kNtpPromoViews); |
| 180 prefs->ClearPref(prefs::kNtpPromoClosed); | 202 prefs->ClearPref(prefs::kNtpPromoClosed); |
| 181 prefs->ClearPref(prefs::kNtpPromoGplusRequired); | 203 prefs->ClearPref(prefs::kNtpPromoGplusRequired); |
| 182 } | 204 } |
| 183 | 205 |
| 184 } // namespace | 206 } // namespace |
| 185 | 207 |
| 186 const char NotificationPromo::kNtpNotificationPromoType[] = | |
| 187 "ntp_notification_promo"; | |
| 188 const char NotificationPromo::kBubblePromoType[] = "bubble_promo"; | |
| 189 | |
| 190 NotificationPromo::NotificationPromo(Profile* profile) | 208 NotificationPromo::NotificationPromo(Profile* profile) |
| 191 : profile_(profile), | 209 : profile_(profile), |
| 192 prefs_(profile_->GetPrefs()), | 210 prefs_(profile_->GetPrefs()), |
| 193 promo_type_(kNtpNotificationPromoType), | 211 promo_type_(NO_PROMO), |
| 194 #if defined(OS_ANDROID) | 212 #if defined(OS_ANDROID) |
| 195 promo_action_args_(new base::ListValue), | 213 promo_action_args_(new base::ListValue), |
| 196 #endif // defined(OS_ANDROID) | 214 #endif |
| 197 start_(0.0), | 215 start_(0.0), |
| 198 end_(0.0), | 216 end_(0.0), |
| 199 num_groups_(kDefaultGroupSize), | 217 num_groups_(kDefaultGroupSize), |
| 200 initial_segment_(0), | 218 initial_segment_(0), |
| 201 increment_(1), | 219 increment_(1), |
| 202 time_slice_(0), | 220 time_slice_(0), |
| 203 max_group_(0), | 221 max_group_(0), |
| 204 max_views_(0), | 222 max_views_(0), |
| 205 group_(0), | 223 group_(0), |
| 206 views_(0), | 224 views_(0), |
| 207 closed_(false), | 225 closed_(false), |
| 208 gplus_required_(false), | 226 gplus_required_(false), |
| 209 new_notification_(false) { | 227 new_notification_(false) { |
| 210 DCHECK(profile); | 228 DCHECK(profile); |
| 211 DCHECK(prefs_); | 229 DCHECK(prefs_); |
| 212 } | 230 } |
| 213 | 231 |
| 214 NotificationPromo::~NotificationPromo() {} | 232 NotificationPromo::~NotificationPromo() {} |
| 215 | 233 |
| 216 void NotificationPromo::InitFromJson(const DictionaryValue& json) { | 234 void NotificationPromo::InitFromJson(const DictionaryValue& json, |
| 235 PromoType promo_type) { |
| 236 promo_type_ = promo_type; |
| 217 const ListValue* promo_list = NULL; | 237 const ListValue* promo_list = NULL; |
| 218 #if !defined(OS_ANDROID) | 238 if (!json.GetList(PromoTypeToString(promo_type_), &promo_list)) { |
| 219 if (!json.GetList(promo_type_, &promo_list)) | 239 LOG(ERROR) << "Malformed JSON: not " << PromoTypeToString(promo_type_); |
| 220 return; | |
| 221 #else | |
| 222 if (!json.GetList("mobile_ntp_sync_promo", &promo_list)) { | |
| 223 LOG(ERROR) << "Malfromed JSON: not a mobile_ntp_sync_promo"; | |
| 224 return; | 240 return; |
| 225 } | 241 } |
| 226 #endif // !defined(OS_ANDROID) | |
| 227 | 242 |
| 228 // No support for multiple promos yet. Only consider the first one. | 243 // No support for multiple promos yet. Only consider the first one. |
| 229 const DictionaryValue* promo = NULL; | 244 const DictionaryValue* promo = NULL; |
| 230 if (!promo_list->GetDictionary(0, &promo)) | 245 if (!promo_list->GetDictionary(0, &promo)) |
| 231 return; | 246 return; |
| 232 | 247 |
| 233 // Strings. Assume the first one is the promo text. | 248 // Strings. Assume the first one is the promo text. |
| 234 const DictionaryValue* strings = NULL; | 249 const DictionaryValue* strings = NULL; |
| 235 if (promo->GetDictionary("strings", &strings)) { | 250 if (promo->GetDictionary("strings", &strings)) { |
| 236 #if !defined(OS_ANDROID) | 251 #if !defined(OS_ANDROID) |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 promo_action_args_->Append(base::Value::CreateStringValue(value)); | 351 promo_action_args_->Append(base::Value::CreateStringValue(value)); |
| 337 } | 352 } |
| 338 } | 353 } |
| 339 #endif // defined(OS_ANDROID) | 354 #endif // defined(OS_ANDROID) |
| 340 | 355 |
| 341 CheckForNewNotification(); | 356 CheckForNewNotification(); |
| 342 } | 357 } |
| 343 | 358 |
| 344 void NotificationPromo::CheckForNewNotification() { | 359 void NotificationPromo::CheckForNewNotification() { |
| 345 NotificationPromo old_promo(profile_); | 360 NotificationPromo old_promo(profile_); |
| 346 old_promo.InitFromPrefs(); | 361 old_promo.InitFromPrefs(promo_type_); |
| 347 const double old_start = old_promo.start_; | 362 const double old_start = old_promo.start_; |
| 348 const double old_end = old_promo.end_; | 363 const double old_end = old_promo.end_; |
| 349 const std::string old_promo_text = old_promo.promo_text_; | 364 const std::string old_promo_text = old_promo.promo_text_; |
| 350 | 365 |
| 351 new_notification_ = | 366 new_notification_ = |
| 352 old_start != start_ || old_end != end_ || old_promo_text != promo_text_; | 367 old_start != start_ || old_end != end_ || old_promo_text != promo_text_; |
| 353 if (new_notification_) | 368 if (new_notification_) |
| 354 OnNewNotification(); | 369 OnNewNotification(); |
| 355 } | 370 } |
| 356 | 371 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 ntp_promo->SetInteger(kPrefPromoGroup, group_); | 408 ntp_promo->SetInteger(kPrefPromoGroup, group_); |
| 394 ntp_promo->SetInteger(kPrefPromoViews, views_); | 409 ntp_promo->SetInteger(kPrefPromoViews, views_); |
| 395 ntp_promo->SetBoolean(kPrefPromoClosed, closed_); | 410 ntp_promo->SetBoolean(kPrefPromoClosed, closed_); |
| 396 | 411 |
| 397 ntp_promo->SetBoolean(kPrefPromoGPlusRequired, gplus_required_); | 412 ntp_promo->SetBoolean(kPrefPromoGPlusRequired, gplus_required_); |
| 398 | 413 |
| 399 base::ListValue* promo_list = new base::ListValue; | 414 base::ListValue* promo_list = new base::ListValue; |
| 400 promo_list->Set(0, ntp_promo); // Only support 1 promo for now. | 415 promo_list->Set(0, ntp_promo); // Only support 1 promo for now. |
| 401 | 416 |
| 402 base::DictionaryValue promo_dict; | 417 base::DictionaryValue promo_dict; |
| 403 promo_dict.Set(promo_type_, promo_list); | 418 promo_dict.Set(PromoTypeToString(promo_type_), promo_list); |
| 404 prefs_->Set(kPrefPromoObject, promo_dict); | 419 prefs_->Set(kPrefPromoObject, promo_dict); |
| 405 } | 420 } |
| 406 | 421 |
| 407 void NotificationPromo::InitFromPrefs() { | 422 void NotificationPromo::InitFromPrefs(PromoType promo_type) { |
| 423 promo_type_ = promo_type; |
| 408 const base::DictionaryValue* promo_dict = | 424 const base::DictionaryValue* promo_dict = |
| 409 prefs_->GetDictionary(kPrefPromoObject); | 425 prefs_->GetDictionary(kPrefPromoObject); |
| 410 if (!promo_dict) | 426 if (!promo_dict) |
| 411 return; | 427 return; |
| 412 | 428 |
| 413 const base::ListValue* promo_list(NULL); | 429 const base::ListValue* promo_list(NULL); |
| 414 promo_dict->GetList(promo_type_, &promo_list); | 430 promo_dict->GetList(PromoTypeToString(promo_type_), &promo_list); |
| 415 if (!promo_list) | 431 if (!promo_list) |
| 416 return; | 432 return; |
| 417 | 433 |
| 418 const base::DictionaryValue* ntp_promo(NULL); | 434 const base::DictionaryValue* ntp_promo(NULL); |
| 419 promo_list->GetDictionary(0, &ntp_promo); | 435 promo_list->GetDictionary(0, &ntp_promo); |
| 420 if (!ntp_promo) | 436 if (!ntp_promo) |
| 421 return; | 437 return; |
| 422 | 438 |
| 423 ntp_promo->GetString(kPrefPromoText, &promo_text_); | 439 ntp_promo->GetString(kPrefPromoText, &promo_text_); |
| 424 #if defined(OS_ANDROID) | 440 #if defined(OS_ANDROID) |
| (...skipping 26 matching lines...) Expand all Loading... |
| 451 bool NotificationPromo::CanShow() const { | 467 bool NotificationPromo::CanShow() const { |
| 452 return !closed_ && | 468 return !closed_ && |
| 453 !promo_text_.empty() && | 469 !promo_text_.empty() && |
| 454 !ExceedsMaxGroup() && | 470 !ExceedsMaxGroup() && |
| 455 !ExceedsMaxViews() && | 471 !ExceedsMaxViews() && |
| 456 base::Time::FromDoubleT(StartTimeForGroup()) < base::Time::Now() && | 472 base::Time::FromDoubleT(StartTimeForGroup()) < base::Time::Now() && |
| 457 base::Time::FromDoubleT(EndTime()) > base::Time::Now() && | 473 base::Time::FromDoubleT(EndTime()) > base::Time::Now() && |
| 458 IsGPlusRequired(); | 474 IsGPlusRequired(); |
| 459 } | 475 } |
| 460 | 476 |
| 461 void NotificationPromo::HandleClosed() { | 477 // static |
| 478 void NotificationPromo::HandleClosed(Profile* profile, PromoType promo_type) { |
| 462 content::RecordAction(UserMetricsAction("NTPPromoClosed")); | 479 content::RecordAction(UserMetricsAction("NTPPromoClosed")); |
| 463 InitFromPrefs(); | 480 NotificationPromo promo(profile); |
| 464 if (!closed_) { | 481 promo.InitFromPrefs(promo_type); |
| 465 closed_ = true; | 482 if (!promo.closed_) { |
| 466 WritePrefs(); | 483 promo.closed_ = true; |
| 484 promo.WritePrefs(); |
| 467 } | 485 } |
| 468 } | 486 } |
| 469 | 487 |
| 470 bool NotificationPromo::HandleViewed() { | 488 // static |
| 489 bool NotificationPromo::HandleViewed(Profile* profile, PromoType promo_type) { |
| 471 content::RecordAction(UserMetricsAction("NTPPromoShown")); | 490 content::RecordAction(UserMetricsAction("NTPPromoShown")); |
| 472 InitFromPrefs(); | 491 NotificationPromo promo(profile); |
| 473 ++views_; | 492 promo.InitFromPrefs(promo_type); |
| 474 WritePrefs(); | 493 ++promo.views_; |
| 475 return ExceedsMaxViews(); | 494 promo.WritePrefs(); |
| 495 return promo.ExceedsMaxViews(); |
| 476 } | 496 } |
| 477 | 497 |
| 478 bool NotificationPromo::ExceedsMaxGroup() const { | 498 bool NotificationPromo::ExceedsMaxGroup() const { |
| 479 return (max_group_ == 0) ? false : group_ >= max_group_; | 499 return (max_group_ == 0) ? false : group_ >= max_group_; |
| 480 } | 500 } |
| 481 | 501 |
| 482 bool NotificationPromo::ExceedsMaxViews() const { | 502 bool NotificationPromo::ExceedsMaxViews() const { |
| 483 return (max_views_ == 0) ? false : views_ >= max_views_; | 503 return (max_views_ == 0) ? false : views_ >= max_views_; |
| 484 } | 504 } |
| 485 | 505 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 505 if (group_ < initial_segment_) | 525 if (group_ < initial_segment_) |
| 506 return start_; | 526 return start_; |
| 507 return start_ + | 527 return start_ + |
| 508 std::ceil(static_cast<float>(group_ - initial_segment_ + 1) / increment_) | 528 std::ceil(static_cast<float>(group_ - initial_segment_ + 1) / increment_) |
| 509 * time_slice_; | 529 * time_slice_; |
| 510 } | 530 } |
| 511 | 531 |
| 512 double NotificationPromo::EndTime() const { | 532 double NotificationPromo::EndTime() const { |
| 513 return end_; | 533 return end_; |
| 514 } | 534 } |
| OLD | NEW |