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 |