Chromium Code Reviews| 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 17 matching lines...) Expand all Loading... | |
| 28 #endif // defined(OS_ANDROID) | 28 #endif // defined(OS_ANDROID) |
| 29 | 29 |
| 30 using content::UserMetricsAction; | 30 using content::UserMetricsAction; |
| 31 | 31 |
| 32 namespace { | 32 namespace { |
| 33 | 33 |
| 34 const int kDefaultGroupSize = 100; | 34 const int kDefaultGroupSize = 100; |
| 35 | 35 |
| 36 const char promo_server_url[] = "https://clients3.google.com/crsignal/client"; | 36 const char promo_server_url[] = "https://clients3.google.com/crsignal/client"; |
| 37 | 37 |
| 38 // The name of the preference that stores the promotion object. | |
| 38 const char kPrefPromoObject[] = "promo"; | 39 const char kPrefPromoObject[] = "promo"; |
| 40 | |
| 41 // Keys in the kPrefPromoObject dictionary; used only here. | |
| 39 const char kPrefPromoText[] = "text"; | 42 const char kPrefPromoText[] = "text"; |
| 40 #if defined(OS_ANDROID) | 43 const char kPrefPromoPayload[] = "payload"; |
| 41 const char kPrefPromoTextLong[] = "text_long"; | |
| 42 const char kPrefPromoActionType[] = "action_type"; | |
| 43 const char kPrefPromoActionArgs[] = "action_args"; | |
| 44 #endif | |
| 45 const char kPrefPromoStart[] = "start"; | 44 const char kPrefPromoStart[] = "start"; |
| 46 const char kPrefPromoEnd[] = "end"; | 45 const char kPrefPromoEnd[] = "end"; |
| 47 const char kPrefPromoNumGroups[] = "num_groups"; | 46 const char kPrefPromoNumGroups[] = "num_groups"; |
| 48 const char kPrefPromoSegment[] = "segment"; | 47 const char kPrefPromoSegment[] = "segment"; |
| 49 const char kPrefPromoIncrement[] = "increment"; | 48 const char kPrefPromoIncrement[] = "increment"; |
| 50 const char kPrefPromoIncrementFrequency[] = "increment_frequency"; | 49 const char kPrefPromoIncrementFrequency[] = "increment_frequency"; |
| 51 const char kPrefPromoIncrementMax[] = "increment_max"; | 50 const char kPrefPromoIncrementMax[] = "increment_max"; |
| 52 const char kPrefPromoMaxViews[] = "max_views"; | 51 const char kPrefPromoMaxViews[] = "max_views"; |
| 53 const char kPrefPromoGroup[] = "group"; | 52 const char kPrefPromoGroup[] = "group"; |
| 54 const char kPrefPromoViews[] = "views"; | 53 const char kPrefPromoViews[] = "views"; |
| 55 const char kPrefPromoClosed[] = "closed"; | 54 const char kPrefPromoClosed[] = "closed"; |
| 56 const char kPrefPromoGPlusRequired[] = "gplus_required"; | 55 const char kPrefPromoGPlusRequired[] = "gplus_required"; |
| 57 | 56 |
| 58 #if defined(OS_ANDROID) | |
| 59 const int kCurrentMobilePayloadFormatVersion = 3; | |
| 60 #endif // defined(OS_ANDROID) | |
| 61 | |
| 62 // Returns a string suitable for the Promo Server URL 'osname' value. | 57 // Returns a string suitable for the Promo Server URL 'osname' value. |
| 63 std::string PlatformString() { | 58 std::string PlatformString() { |
| 64 #if defined(OS_WIN) | 59 #if defined(OS_WIN) |
| 65 return "win"; | 60 return "win"; |
| 66 #elif defined(OS_IOS) | 61 #elif defined(OS_IOS) |
| 67 // TODO(noyau): add iOS-specific implementation | 62 // TODO(noyau): add iOS-specific implementation |
| 68 const bool isTablet = false; | 63 const bool isTablet = false; |
| 69 return std::string("ios-") + (isTablet ? "tablet" : "phone"); | 64 return std::string("ios-") + (isTablet ? "tablet" : "phone"); |
| 70 #elif defined(OS_MACOSX) | 65 #elif defined(OS_MACOSX) |
| 71 return "mac"; | 66 return "mac"; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 120 // Convert PromoType to appropriate string. | 115 // Convert PromoType to appropriate string. |
| 121 const char* PromoTypeToString(NotificationPromo::PromoType promo_type) { | 116 const char* PromoTypeToString(NotificationPromo::PromoType promo_type) { |
| 122 for (size_t i = 0; i < arraysize(kPromoMap); ++i) { | 117 for (size_t i = 0; i < arraysize(kPromoMap); ++i) { |
| 123 if (kPromoMap[i].promo_type == promo_type) | 118 if (kPromoMap[i].promo_type == promo_type) |
| 124 return kPromoMap[i].promo_type_str; | 119 return kPromoMap[i].promo_type_str; |
| 125 } | 120 } |
| 126 NOTREACHED(); | 121 NOTREACHED(); |
| 127 return ""; | 122 return ""; |
| 128 } | 123 } |
| 129 | 124 |
| 130 // TODO(achuith): remove this in m23. | 125 // TODO(achuith): http://crbug.com/143773 remove this by m24 |
|
achuithb
2012/08/22 19:49:20
thank you!
aruslan
2012/08/23 00:49:59
You are welcome!
| |
| 131 void ClearDeprecatedPrefs(PrefService* prefs) { | 126 void ClearDeprecatedPrefs(PrefService* prefs) { |
| 132 prefs->RegisterStringPref(prefs::kNtpPromoLine, | 127 prefs->RegisterStringPref(prefs::kNtpPromoLine, |
|
achuithb
2012/08/22 19:49:20
Do you think you could do the same thing you're do
aruslan
2012/08/23 00:49:59
Done.
| |
| 133 std::string(), | 128 std::string(), |
| 134 PrefService::UNSYNCABLE_PREF); | 129 PrefService::UNSYNCABLE_PREF); |
| 135 prefs->ClearPref(prefs::kNtpPromoLine); | 130 prefs->ClearPref(prefs::kNtpPromoLine); |
| 136 #if defined(OS_ANDROID) | 131 |
| 137 prefs->RegisterStringPref(prefs::kNtpPromoLineLong, | 132 #if defined(OS_ANDROID) || defined(OS_IOS) |
| 133 const char kNtpPromoLineLong[] = "ntp.promo_line_long"; | |
| 134 const char kNtpPromoActionType[] = "ntp.promo_action_type"; | |
| 135 const char kNtpPromoActionArgs[] = "ntp.promo_action_args"; | |
| 136 prefs->RegisterStringPref(kNtpPromoLineLong, | |
| 138 std::string(), | 137 std::string(), |
| 139 PrefService::UNSYNCABLE_PREF); | 138 PrefService::UNSYNCABLE_PREF); |
| 140 prefs->RegisterStringPref(prefs::kNtpPromoActionType, | 139 prefs->RegisterStringPref(kNtpPromoActionType, |
| 141 std::string(), | 140 std::string(), |
| 142 PrefService::UNSYNCABLE_PREF); | 141 PrefService::UNSYNCABLE_PREF); |
| 143 prefs->RegisterListPref(prefs::kNtpPromoActionArgs, | 142 prefs->RegisterListPref(kNtpPromoActionArgs, |
| 144 new base::ListValue, | 143 new base::ListValue, |
| 145 PrefService::UNSYNCABLE_PREF); | 144 PrefService::UNSYNCABLE_PREF); |
| 146 prefs->ClearPref(prefs::kNtpPromoLineLong); | 145 prefs->ClearPref(kNtpPromoLineLong); |
| 147 prefs->ClearPref(prefs::kNtpPromoActionType); | 146 prefs->ClearPref(kNtpPromoActionType); |
| 148 prefs->ClearPref(prefs::kNtpPromoActionArgs); | 147 prefs->ClearPref(kNtpPromoActionArgs); |
| 149 #endif // defined(OS_ANDROID) | 148 #endif // defined(OS_ANDROID) || defined(OS_IOS) |
| 150 | 149 |
| 151 prefs->RegisterDoublePref(prefs::kNtpPromoStart, | 150 prefs->RegisterDoublePref(prefs::kNtpPromoStart, |
| 152 0, | 151 0, |
| 153 PrefService::UNSYNCABLE_PREF); | 152 PrefService::UNSYNCABLE_PREF); |
| 154 prefs->RegisterDoublePref(prefs::kNtpPromoEnd, | 153 prefs->RegisterDoublePref(prefs::kNtpPromoEnd, |
| 155 0, | 154 0, |
| 156 PrefService::UNSYNCABLE_PREF); | 155 PrefService::UNSYNCABLE_PREF); |
| 157 | 156 |
| 158 prefs->RegisterIntegerPref(prefs::kNtpPromoNumGroups, | 157 prefs->RegisterIntegerPref(prefs::kNtpPromoNumGroups, |
| 159 0, | 158 0, |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 196 prefs->ClearPref(prefs::kNtpPromoIncrement); | 195 prefs->ClearPref(prefs::kNtpPromoIncrement); |
| 197 prefs->ClearPref(prefs::kNtpPromoGroupTimeSlice); | 196 prefs->ClearPref(prefs::kNtpPromoGroupTimeSlice); |
| 198 prefs->ClearPref(prefs::kNtpPromoGroupMax); | 197 prefs->ClearPref(prefs::kNtpPromoGroupMax); |
| 199 prefs->ClearPref(prefs::kNtpPromoViewsMax); | 198 prefs->ClearPref(prefs::kNtpPromoViewsMax); |
| 200 prefs->ClearPref(prefs::kNtpPromoGroup); | 199 prefs->ClearPref(prefs::kNtpPromoGroup); |
| 201 prefs->ClearPref(prefs::kNtpPromoViews); | 200 prefs->ClearPref(prefs::kNtpPromoViews); |
| 202 prefs->ClearPref(prefs::kNtpPromoClosed); | 201 prefs->ClearPref(prefs::kNtpPromoClosed); |
| 203 prefs->ClearPref(prefs::kNtpPromoGplusRequired); | 202 prefs->ClearPref(prefs::kNtpPromoGplusRequired); |
| 204 } | 203 } |
| 205 | 204 |
| 205 // Deep-copies a node, replacing any "value" that is a key | |
| 206 // into "strings" dictionary with its value from "strings". | |
| 207 // E.g. for | |
| 208 // {promo_action_args:['MSG_SHORT']} + strings:{MSG_SHORT:'yes'} | |
| 209 // it will return | |
| 210 // {promo_action_args:['yes']} | |
| 211 // |node| - a value to be deep copied and resolved. | |
| 212 // |strings| - a dictionary of strings to be used for resolution. | |
| 213 // Returns a _new_ object that is a deep copy with replacements. | |
| 214 base::Value* DeepCopyAndResolveStrings( | |
|
Dan Beam
2012/08/22 19:43:27
it might be useful to put a TODO() to create a Dic
aruslan
2012/08/23 00:49:59
TODO+http://crbug.com/144320 added.
| |
| 215 const base::Value* node, | |
| 216 const base::DictionaryValue* strings) { | |
| 217 switch (node->GetType()) { | |
| 218 case base::Value::TYPE_LIST: { | |
| 219 const base::ListValue* list = static_cast<const base::ListValue*>(node); | |
| 220 base::ListValue* copy = new base::ListValue; | |
| 221 for (base::ListValue::const_iterator it = list->begin(); | |
| 222 it != list->end(); ++it) { | |
| 223 base::Value* child_copy = DeepCopyAndResolveStrings(*it, strings); | |
| 224 copy->Append(child_copy); | |
| 225 } | |
| 226 return copy; | |
| 227 } | |
| 228 | |
| 229 case Value::TYPE_DICTIONARY: { | |
| 230 const base::DictionaryValue* dict = | |
| 231 static_cast<const base::DictionaryValue*>(node); | |
| 232 base::DictionaryValue* copy = new base::DictionaryValue; | |
| 233 for (base::DictionaryValue::key_iterator it = dict->begin_keys(); | |
| 234 it != dict->end_keys(); ++it) { | |
| 235 const base::Value* child = NULL; | |
| 236 bool rv = dict->GetWithoutPathExpansion(*it, &child); | |
| 237 DCHECK(rv); | |
| 238 base::Value* child_copy = DeepCopyAndResolveStrings(child, strings); | |
| 239 copy->SetWithoutPathExpansion(*it, child_copy); | |
| 240 } | |
| 241 return copy; | |
| 242 } | |
| 243 | |
| 244 case Value::TYPE_STRING: { | |
| 245 const base::StringValue* str = | |
| 246 static_cast<const base::StringValue*>(node); | |
| 247 std::string value; | |
| 248 bool rv = str->GetAsString(&value); | |
| 249 DCHECK(rv); | |
| 250 std::string actual_value; | |
| 251 if (!strings || !strings->GetString(value, &actual_value)) | |
| 252 actual_value = value; | |
| 253 return new base::StringValue(actual_value); | |
| 254 } | |
| 255 | |
| 256 default: | |
| 257 // For everything else, just make a copy. | |
| 258 return node->DeepCopy(); | |
| 259 } | |
| 260 } | |
| 261 | |
| 206 } // namespace | 262 } // namespace |
| 207 | 263 |
| 208 NotificationPromo::NotificationPromo(Profile* profile) | 264 NotificationPromo::NotificationPromo(Profile* profile) |
| 209 : profile_(profile), | 265 : profile_(profile), |
| 210 prefs_(profile_->GetPrefs()), | 266 prefs_(profile_->GetPrefs()), |
| 211 promo_type_(NO_PROMO), | 267 promo_type_(NO_PROMO), |
| 212 #if defined(OS_ANDROID) | 268 promo_payload_(new base::DictionaryValue()), |
| 213 promo_action_args_(new base::ListValue), | |
| 214 #endif | |
| 215 start_(0.0), | 269 start_(0.0), |
| 216 end_(0.0), | 270 end_(0.0), |
| 217 num_groups_(kDefaultGroupSize), | 271 num_groups_(kDefaultGroupSize), |
| 218 initial_segment_(0), | 272 initial_segment_(0), |
| 219 increment_(1), | 273 increment_(1), |
| 220 time_slice_(0), | 274 time_slice_(0), |
| 221 max_group_(0), | 275 max_group_(0), |
| 222 max_views_(0), | 276 max_views_(0), |
| 223 group_(0), | 277 group_(0), |
| 224 views_(0), | 278 views_(0), |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 238 if (!json.GetList(PromoTypeToString(promo_type_), &promo_list)) { | 292 if (!json.GetList(PromoTypeToString(promo_type_), &promo_list)) { |
| 239 LOG(ERROR) << "Malformed JSON: not " << PromoTypeToString(promo_type_); | 293 LOG(ERROR) << "Malformed JSON: not " << PromoTypeToString(promo_type_); |
| 240 return; | 294 return; |
| 241 } | 295 } |
| 242 | 296 |
| 243 // No support for multiple promos yet. Only consider the first one. | 297 // No support for multiple promos yet. Only consider the first one. |
| 244 const DictionaryValue* promo = NULL; | 298 const DictionaryValue* promo = NULL; |
| 245 if (!promo_list->GetDictionary(0, &promo)) | 299 if (!promo_list->GetDictionary(0, &promo)) |
| 246 return; | 300 return; |
| 247 | 301 |
| 248 // Strings. Assume the first one is the promo text. | |
| 249 const DictionaryValue* strings = NULL; | |
| 250 if (promo->GetDictionary("strings", &strings)) { | |
| 251 #if !defined(OS_ANDROID) | |
| 252 DictionaryValue::Iterator iter(*strings); | |
| 253 iter.value().GetAsString(&promo_text_); | |
| 254 DVLOG(1) << "promo_text_=" << promo_text_; | |
| 255 #endif // defined(OS_ANDROID) | |
| 256 } | |
| 257 | |
| 258 // Date. | 302 // Date. |
| 259 const ListValue* date_list = NULL; | 303 const ListValue* date_list = NULL; |
| 260 if (promo->GetList("date", &date_list)) { | 304 if (promo->GetList("date", &date_list)) { |
| 261 const DictionaryValue* date; | 305 const DictionaryValue* date; |
| 262 if (date_list->GetDictionary(0, &date)) { | 306 if (date_list->GetDictionary(0, &date)) { |
| 263 std::string time_str; | 307 std::string time_str; |
| 264 base::Time time; | 308 base::Time time; |
| 265 if (date->GetString("start", &time_str) && | 309 if (date->GetString("start", &time_str) && |
| 266 base::Time::FromString(time_str.c_str(), &time)) { | 310 base::Time::FromString(time_str.c_str(), &time)) { |
| 267 start_ = time.ToDoubleT(); | 311 start_ = time.ToDoubleT(); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 286 grouping->GetInteger("increment_frequency", &time_slice_); | 330 grouping->GetInteger("increment_frequency", &time_slice_); |
| 287 grouping->GetInteger("increment_max", &max_group_); | 331 grouping->GetInteger("increment_max", &max_group_); |
| 288 | 332 |
| 289 DVLOG(1) << "num_groups_ = " << num_groups_ | 333 DVLOG(1) << "num_groups_ = " << num_groups_ |
| 290 << ", initial_segment_ = " << initial_segment_ | 334 << ", initial_segment_ = " << initial_segment_ |
| 291 << ", increment_ = " << increment_ | 335 << ", increment_ = " << increment_ |
| 292 << ", time_slice_ = " << time_slice_ | 336 << ", time_slice_ = " << time_slice_ |
| 293 << ", max_group_ = " << max_group_; | 337 << ", max_group_ = " << max_group_; |
| 294 } | 338 } |
| 295 | 339 |
| 340 // Strings. | |
| 341 const DictionaryValue* strings = NULL; | |
| 342 promo->GetDictionary("strings", &strings); | |
| 343 | |
| 296 // Payload. | 344 // Payload. |
| 297 const DictionaryValue* payload = NULL; | 345 const DictionaryValue* payload = NULL; |
| 298 if (promo->GetDictionary("payload", &payload)) { | 346 if (promo->GetDictionary("payload", &payload)) { |
| 299 payload->GetBoolean("gplus_required", &gplus_required_); | 347 payload->GetBoolean("gplus_required", &gplus_required_); |
| 348 DVLOG(1) << "gplus_required_ = " << gplus_required_; | |
| 300 | 349 |
| 301 DVLOG(1) << "gplus_required_ = " << gplus_required_; | 350 base::Value* ppcopy = DeepCopyAndResolveStrings(payload, strings); |
| 351 DCHECK(ppcopy && ppcopy->IsType(base::Value::TYPE_DICTIONARY)); | |
| 352 promo_payload_.reset(static_cast<base::DictionaryValue*>(ppcopy)); | |
| 302 } | 353 } |
| 303 | 354 |
| 355 if (!promo_payload_->GetString("promo_message_short", &promo_text_) && | |
| 356 strings) { | |
| 357 // For compatibility with the legacy desktop version, | |
| 358 // if no |payload.promo_message_short| is specified, | |
| 359 // the first string in |strings| is used. | |
| 360 DictionaryValue::Iterator iter(*strings); | |
| 361 iter.value().GetAsString(&promo_text_); | |
| 362 } | |
| 363 DVLOG(1) << "promo_text_=" << promo_text_; | |
| 364 | |
| 304 promo->GetInteger("max_views", &max_views_); | 365 promo->GetInteger("max_views", &max_views_); |
| 305 DVLOG(1) << "max_views_ " << max_views_; | 366 DVLOG(1) << "max_views_ " << max_views_; |
| 306 | 367 |
| 307 #if defined(OS_ANDROID) | |
| 308 int payload_version = 0; | |
| 309 if (!payload) { | |
| 310 LOG(ERROR) << "Malformed JSON: no payload"; | |
| 311 return; | |
| 312 } | |
| 313 if (!strings) { | |
| 314 LOG(ERROR) << "Malformed JSON: no strings"; | |
| 315 return; | |
| 316 } | |
| 317 if (!payload->GetInteger("payload_format_version", &payload_version) || | |
| 318 payload_version != kCurrentMobilePayloadFormatVersion) { | |
| 319 LOG(ERROR) << "Unsupported promo payload_format_version " << payload_version | |
| 320 << "; expected " << kCurrentMobilePayloadFormatVersion; | |
| 321 return; | |
| 322 } | |
| 323 std::string promo_key_short; | |
| 324 std::string promo_key_long; | |
| 325 if (!payload->GetString("promo_message_short", &promo_key_short) || | |
| 326 !payload->GetString("promo_message_long", &promo_key_long) || | |
| 327 !strings->GetString(promo_key_short, &promo_text_) || | |
| 328 !strings->GetString(promo_key_long, &promo_text_long_)) { | |
| 329 LOG(ERROR) << "Malformed JSON: no promo_message_short or _long"; | |
| 330 return; | |
| 331 } | |
| 332 payload->GetString("promo_action_type", &promo_action_type_); | |
| 333 // We need to be idempotent as the tests call us more than once. | |
| 334 promo_action_args_.reset(new base::ListValue); | |
| 335 const ListValue* args; | |
| 336 if (payload->GetList("promo_action_args", &args)) { | |
| 337 // JSON format for args: "promo_action_args" : [ "<arg1>", "<arg2>"... ] | |
| 338 // Every value comes from "strings" dictionary, either directly or not. | |
| 339 // Every arg is either directly a key into "strings" dictionary, | |
| 340 // or a key into "payload" dictionary with the value that is a key into | |
| 341 // "strings" dictionary. | |
| 342 for (std::size_t i = 0; i < args->GetSize(); ++i) { | |
| 343 std::string name, key, value; | |
| 344 if (!args->GetString(i, &name) || | |
| 345 !(strings->GetString(name, &value) || | |
| 346 (payload->GetString(name, &key) && | |
| 347 strings->GetString(key, &value)))) { | |
| 348 LOG(ERROR) << "Malformed JSON: failed to parse promo_action_args"; | |
| 349 return; | |
| 350 } | |
| 351 promo_action_args_->Append(base::Value::CreateStringValue(value)); | |
| 352 } | |
| 353 } | |
| 354 #endif // defined(OS_ANDROID) | |
| 355 | |
| 356 CheckForNewNotification(); | 368 CheckForNewNotification(); |
| 357 } | 369 } |
| 358 | 370 |
| 359 void NotificationPromo::CheckForNewNotification() { | 371 void NotificationPromo::CheckForNewNotification() { |
| 360 NotificationPromo old_promo(profile_); | 372 NotificationPromo old_promo(profile_); |
| 361 old_promo.InitFromPrefs(promo_type_); | 373 old_promo.InitFromPrefs(promo_type_); |
| 362 const double old_start = old_promo.start_; | 374 const double old_start = old_promo.start_; |
| 363 const double old_end = old_promo.end_; | 375 const double old_end = old_promo.end_; |
| 364 const std::string old_promo_text = old_promo.promo_text_; | 376 const std::string old_promo_text = old_promo.promo_text_; |
| 365 | 377 |
| 366 new_notification_ = | 378 new_notification_ = |
| 367 old_start != start_ || old_end != end_ || old_promo_text != promo_text_; | 379 old_start != start_ || old_end != end_ || old_promo_text != promo_text_; |
| 368 if (new_notification_) | 380 if (new_notification_) |
| 369 OnNewNotification(); | 381 OnNewNotification(); |
| 370 } | 382 } |
| 371 | 383 |
| 372 void NotificationPromo::OnNewNotification() { | 384 void NotificationPromo::OnNewNotification() { |
| 373 DVLOG(1) << "OnNewNotification"; | 385 DVLOG(1) << "OnNewNotification"; |
| 374 // Create a new promo group. | 386 // Create a new promo group. |
| 375 group_ = base::RandInt(0, num_groups_ - 1); | 387 group_ = base::RandInt(0, num_groups_ - 1); |
| 376 WritePrefs(); | 388 WritePrefs(); |
| 377 } | 389 } |
| 378 | 390 |
| 379 // static | 391 // static |
| 380 void NotificationPromo::RegisterUserPrefs(PrefService* prefs) { | 392 void NotificationPromo::RegisterUserPrefs(PrefService* prefs) { |
| 381 ClearDeprecatedPrefs(prefs); | 393 ClearDeprecatedPrefs(prefs); |
| 382 prefs->RegisterDictionaryPref("promo", | 394 prefs->RegisterDictionaryPref(kPrefPromoObject, |
| 383 new base::DictionaryValue, | 395 new base::DictionaryValue, |
| 384 PrefService::UNSYNCABLE_PREF); | 396 PrefService::UNSYNCABLE_PREF); |
| 385 } | 397 } |
| 386 | 398 |
| 387 void NotificationPromo::WritePrefs() { | 399 void NotificationPromo::WritePrefs() { |
| 388 DVLOG(1) << "WritePrefs"; | 400 DVLOG(1) << "WritePrefs"; |
| 389 base::DictionaryValue* ntp_promo = new base::DictionaryValue; | 401 base::DictionaryValue* ntp_promo = new base::DictionaryValue; |
| 390 ntp_promo->SetString(kPrefPromoText, promo_text_); | 402 ntp_promo->SetString(kPrefPromoText, promo_text_); |
| 391 #if defined(OS_ANDROID) | 403 ntp_promo->Set(kPrefPromoPayload, promo_payload_->DeepCopy()); |
| 392 ntp_promo->SetString(kPrefPromoTextLong, promo_text_long_); | |
| 393 ntp_promo->SetString(kPrefPromoActionType, promo_action_type_); | |
| 394 DCHECK(promo_action_args_.get()); | |
| 395 ntp_promo->Set(kPrefPromoActionArgs, promo_action_args_->DeepCopy()); | |
| 396 #endif // defined(OS_ANDROID) | |
| 397 ntp_promo->SetDouble(kPrefPromoStart, start_); | 404 ntp_promo->SetDouble(kPrefPromoStart, start_); |
| 398 ntp_promo->SetDouble(kPrefPromoEnd, end_); | 405 ntp_promo->SetDouble(kPrefPromoEnd, end_); |
| 399 | 406 |
| 400 ntp_promo->SetInteger(kPrefPromoNumGroups, num_groups_); | 407 ntp_promo->SetInteger(kPrefPromoNumGroups, num_groups_); |
| 401 ntp_promo->SetInteger(kPrefPromoSegment, initial_segment_); | 408 ntp_promo->SetInteger(kPrefPromoSegment, initial_segment_); |
| 402 ntp_promo->SetInteger(kPrefPromoIncrement, increment_); | 409 ntp_promo->SetInteger(kPrefPromoIncrement, increment_); |
| 403 ntp_promo->SetInteger(kPrefPromoIncrementFrequency, time_slice_); | 410 ntp_promo->SetInteger(kPrefPromoIncrementFrequency, time_slice_); |
| 404 ntp_promo->SetInteger(kPrefPromoIncrementMax, max_group_); | 411 ntp_promo->SetInteger(kPrefPromoIncrementMax, max_group_); |
| 405 | 412 |
| 406 ntp_promo->SetInteger(kPrefPromoMaxViews, max_views_); | 413 ntp_promo->SetInteger(kPrefPromoMaxViews, max_views_); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 419 prefs_->Set(kPrefPromoObject, promo_dict); | 426 prefs_->Set(kPrefPromoObject, promo_dict); |
| 420 } | 427 } |
| 421 | 428 |
| 422 void NotificationPromo::InitFromPrefs(PromoType promo_type) { | 429 void NotificationPromo::InitFromPrefs(PromoType promo_type) { |
| 423 promo_type_ = promo_type; | 430 promo_type_ = promo_type; |
| 424 const base::DictionaryValue* promo_dict = | 431 const base::DictionaryValue* promo_dict = |
| 425 prefs_->GetDictionary(kPrefPromoObject); | 432 prefs_->GetDictionary(kPrefPromoObject); |
| 426 if (!promo_dict) | 433 if (!promo_dict) |
| 427 return; | 434 return; |
| 428 | 435 |
| 429 const base::ListValue* promo_list(NULL); | 436 const base::ListValue* promo_list = NULL; |
| 430 promo_dict->GetList(PromoTypeToString(promo_type_), &promo_list); | 437 promo_dict->GetList(PromoTypeToString(promo_type_), &promo_list); |
| 431 if (!promo_list) | 438 if (!promo_list) |
| 432 return; | 439 return; |
| 433 | 440 |
| 434 const base::DictionaryValue* ntp_promo(NULL); | 441 const base::DictionaryValue* ntp_promo = NULL; |
| 435 promo_list->GetDictionary(0, &ntp_promo); | 442 promo_list->GetDictionary(0, &ntp_promo); |
| 436 if (!ntp_promo) | 443 if (!ntp_promo) |
| 437 return; | 444 return; |
| 438 | 445 |
| 439 ntp_promo->GetString(kPrefPromoText, &promo_text_); | 446 ntp_promo->GetString(kPrefPromoText, &promo_text_); |
| 440 #if defined(OS_ANDROID) | 447 const base::DictionaryValue* dv = NULL; |
|
achuithb
2012/08/22 19:49:20
do you mind calling this var payload instead?
aruslan
2012/08/23 00:49:59
Done.
| |
| 441 ntp_promo->GetString(kPrefPromoTextLong, &promo_text_long_); | 448 if (ntp_promo->GetDictionary(kPrefPromoPayload, &dv)) |
| 442 ntp_promo->GetString(kPrefPromoActionType, &promo_action_type_); | 449 promo_payload_.reset(dv->DeepCopy()); |
| 443 const base::ListValue* lv(NULL); | |
| 444 ntp_promo->GetList(kPrefPromoActionArgs, &lv); | |
| 445 DCHECK(lv != NULL); | |
| 446 promo_action_args_.reset(lv->DeepCopy()); | |
| 447 #endif // defined(OS_ANDROID) | |
| 448 | 450 |
| 449 ntp_promo->GetDouble(kPrefPromoStart, &start_); | 451 ntp_promo->GetDouble(kPrefPromoStart, &start_); |
| 450 ntp_promo->GetDouble(kPrefPromoEnd, &end_); | 452 ntp_promo->GetDouble(kPrefPromoEnd, &end_); |
| 451 | 453 |
| 452 ntp_promo->GetInteger(kPrefPromoNumGroups, &num_groups_); | 454 ntp_promo->GetInteger(kPrefPromoNumGroups, &num_groups_); |
| 453 ntp_promo->GetInteger(kPrefPromoSegment, &initial_segment_); | 455 ntp_promo->GetInteger(kPrefPromoSegment, &initial_segment_); |
| 454 ntp_promo->GetInteger(kPrefPromoIncrement, &increment_); | 456 ntp_promo->GetInteger(kPrefPromoIncrement, &increment_); |
| 455 ntp_promo->GetInteger(kPrefPromoIncrementFrequency, &time_slice_); | 457 ntp_promo->GetInteger(kPrefPromoIncrementFrequency, &time_slice_); |
| 456 ntp_promo->GetInteger(kPrefPromoIncrementMax, &max_group_); | 458 ntp_promo->GetInteger(kPrefPromoIncrementMax, &max_group_); |
| 457 | 459 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 525 if (group_ < initial_segment_) | 527 if (group_ < initial_segment_) |
| 526 return start_; | 528 return start_; |
| 527 return start_ + | 529 return start_ + |
| 528 std::ceil(static_cast<float>(group_ - initial_segment_ + 1) / increment_) | 530 std::ceil(static_cast<float>(group_ - initial_segment_ + 1) / increment_) |
| 529 * time_slice_; | 531 * time_slice_; |
| 530 } | 532 } |
| 531 | 533 |
| 532 double NotificationPromo::EndTime() const { | 534 double NotificationPromo::EndTime() const { |
| 533 return end_; | 535 return end_; |
| 534 } | 536 } |
| OLD | NEW |