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 // TODO(achuith): Shouldn't this be in pref_names? | |
| 38 const char kPrefPromoObject[] = "promo"; | 39 const char kPrefPromoObject[] = "promo"; |
| 40 | |
| 41 // Keys into 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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 126 NOTREACHED(); | 121 NOTREACHED(); |
| 127 return ""; | 122 return ""; |
| 128 } | 123 } |
| 129 | 124 |
| 130 // TODO(achuith): remove this in m23. | 125 // TODO(achuith): remove this in m23. |
| 131 void ClearDeprecatedPrefs(PrefService* prefs) { | 126 void ClearDeprecatedPrefs(PrefService* prefs) { |
| 132 prefs->RegisterStringPref(prefs::kNtpPromoLine, | 127 prefs->RegisterStringPref(prefs::kNtpPromoLine, |
| 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) | |
|
achuithb
2012/08/17 22:55:12
Why remove this? We can probably keep it for anoth
aruslan
2012/08/20 15:36:53
I do not think removing mobile-specific prefs woul
| |
| 137 prefs->RegisterStringPref(prefs::kNtpPromoLineLong, | |
| 138 std::string(), | |
| 139 PrefService::UNSYNCABLE_PREF); | |
| 140 prefs->RegisterStringPref(prefs::kNtpPromoActionType, | |
| 141 std::string(), | |
| 142 PrefService::UNSYNCABLE_PREF); | |
| 143 prefs->RegisterListPref(prefs::kNtpPromoActionArgs, | |
| 144 new base::ListValue, | |
| 145 PrefService::UNSYNCABLE_PREF); | |
| 146 prefs->ClearPref(prefs::kNtpPromoLineLong); | |
| 147 prefs->ClearPref(prefs::kNtpPromoActionType); | |
| 148 prefs->ClearPref(prefs::kNtpPromoActionArgs); | |
| 149 #endif // defined(OS_ANDROID) | |
| 150 | |
| 151 prefs->RegisterDoublePref(prefs::kNtpPromoStart, | 131 prefs->RegisterDoublePref(prefs::kNtpPromoStart, |
| 152 0, | 132 0, |
| 153 PrefService::UNSYNCABLE_PREF); | 133 PrefService::UNSYNCABLE_PREF); |
| 154 prefs->RegisterDoublePref(prefs::kNtpPromoEnd, | 134 prefs->RegisterDoublePref(prefs::kNtpPromoEnd, |
| 155 0, | 135 0, |
| 156 PrefService::UNSYNCABLE_PREF); | 136 PrefService::UNSYNCABLE_PREF); |
| 157 | 137 |
| 158 prefs->RegisterIntegerPref(prefs::kNtpPromoNumGroups, | 138 prefs->RegisterIntegerPref(prefs::kNtpPromoNumGroups, |
| 159 0, | 139 0, |
| 160 PrefService::UNSYNCABLE_PREF); | 140 PrefService::UNSYNCABLE_PREF); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 196 prefs->ClearPref(prefs::kNtpPromoIncrement); | 176 prefs->ClearPref(prefs::kNtpPromoIncrement); |
| 197 prefs->ClearPref(prefs::kNtpPromoGroupTimeSlice); | 177 prefs->ClearPref(prefs::kNtpPromoGroupTimeSlice); |
| 198 prefs->ClearPref(prefs::kNtpPromoGroupMax); | 178 prefs->ClearPref(prefs::kNtpPromoGroupMax); |
| 199 prefs->ClearPref(prefs::kNtpPromoViewsMax); | 179 prefs->ClearPref(prefs::kNtpPromoViewsMax); |
| 200 prefs->ClearPref(prefs::kNtpPromoGroup); | 180 prefs->ClearPref(prefs::kNtpPromoGroup); |
| 201 prefs->ClearPref(prefs::kNtpPromoViews); | 181 prefs->ClearPref(prefs::kNtpPromoViews); |
| 202 prefs->ClearPref(prefs::kNtpPromoClosed); | 182 prefs->ClearPref(prefs::kNtpPromoClosed); |
| 203 prefs->ClearPref(prefs::kNtpPromoGplusRequired); | 183 prefs->ClearPref(prefs::kNtpPromoGplusRequired); |
| 204 } | 184 } |
| 205 | 185 |
| 186 // Deep-copies a node, replacing any "value" that is a key | |
| 187 // into "strings" dictionary with its value from "strings". | |
| 188 // E.g. for | |
| 189 // {promo_action_args:['MSG_SHORT']} + strings:{MSG_SHORT:'yes'} | |
| 190 // it will return | |
| 191 // {promo_action_args:['yes']} | |
| 192 base::Value* deepCopyAndResolveStrings( | |
|
achuithb
2012/08/17 22:55:12
DeepCopyAndResolveStrings.
Also, can we return sc
aruslan
2012/08/20 15:36:53
Renamed to DeepCopyAndResolveStrings -- done.
I ha
| |
| 193 const base::Value* node, | |
| 194 const base::DictionaryValue* strings) { | |
| 195 DCHECK(node); | |
|
achuithb
2012/08/17 22:55:12
this DCHECK is pointless. Let's get rid of it.
aruslan
2012/08/20 15:36:53
Done.
| |
| 196 switch (node->GetType()) { | |
| 197 case base::Value::TYPE_LIST: { | |
| 198 const base::ListValue* list = static_cast<const base::ListValue*>(node); | |
| 199 base::ListValue* copy = new base::ListValue; | |
| 200 for (base::ListValue::const_iterator it = list->begin(); | |
| 201 it != list->end(); | |
| 202 ++it) { | |
| 203 base::Value* child_copy = deepCopyAndResolveStrings(*it, strings); | |
| 204 copy->Append(child_copy); | |
| 205 } | |
| 206 return copy; | |
| 207 } | |
| 208 | |
| 209 case Value::TYPE_DICTIONARY: { | |
| 210 const base::DictionaryValue* dict = | |
| 211 static_cast<const base::DictionaryValue*>(node); | |
| 212 base::DictionaryValue* copy = new base::DictionaryValue; | |
| 213 for (base::DictionaryValue::key_iterator it = dict->begin_keys(); | |
| 214 it != dict->end_keys(); ++it) { | |
| 215 const base::Value* child = NULL; | |
| 216 bool rv = dict->GetWithoutPathExpansion(*it, &child); | |
| 217 DCHECK(rv); | |
| 218 base::Value* child_copy = deepCopyAndResolveStrings(child, strings); | |
| 219 copy->SetWithoutPathExpansion(*it, child_copy); | |
| 220 } | |
| 221 return copy; | |
| 222 } | |
| 223 | |
| 224 case Value::TYPE_STRING: { | |
| 225 const base::StringValue* str = | |
| 226 static_cast<const base::StringValue*>(node); | |
| 227 std::string value; | |
| 228 bool rv = str->GetAsString(&value); | |
| 229 DCHECK(rv); | |
| 230 std::string actual_value; | |
| 231 if (!strings || !strings->GetString(value, &actual_value)) | |
| 232 actual_value = value; | |
| 233 base::StringValue* copy = new base::StringValue(actual_value); | |
|
achuithb
2012/08/17 22:55:12
This temporary seems unnecessary. Why not just
ret
aruslan
2012/08/20 15:36:53
Done.
| |
| 234 return copy; | |
| 235 } | |
| 236 | |
| 237 default: | |
| 238 // For everything else, just make a copy. | |
| 239 return node->DeepCopy(); | |
| 240 } | |
| 241 } | |
| 242 | |
| 206 } // namespace | 243 } // namespace |
| 207 | 244 |
| 208 NotificationPromo::NotificationPromo(Profile* profile) | 245 NotificationPromo::NotificationPromo(Profile* profile) |
| 209 : profile_(profile), | 246 : profile_(profile), |
| 210 prefs_(profile_->GetPrefs()), | 247 prefs_(profile_->GetPrefs()), |
| 211 promo_type_(NO_PROMO), | 248 promo_type_(NO_PROMO), |
| 212 #if defined(OS_ANDROID) | 249 promo_payload_(new base::DictionaryValue()), |
| 213 promo_action_args_(new base::ListValue), | |
| 214 #endif | |
| 215 start_(0.0), | 250 start_(0.0), |
| 216 end_(0.0), | 251 end_(0.0), |
| 217 num_groups_(kDefaultGroupSize), | 252 num_groups_(kDefaultGroupSize), |
| 218 initial_segment_(0), | 253 initial_segment_(0), |
| 219 increment_(1), | 254 increment_(1), |
| 220 time_slice_(0), | 255 time_slice_(0), |
| 221 max_group_(0), | 256 max_group_(0), |
| 222 max_views_(0), | 257 max_views_(0), |
| 223 group_(0), | 258 group_(0), |
| 224 views_(0), | 259 views_(0), |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 238 if (!json.GetList(PromoTypeToString(promo_type_), &promo_list)) { | 273 if (!json.GetList(PromoTypeToString(promo_type_), &promo_list)) { |
| 239 LOG(ERROR) << "Malformed JSON: not " << PromoTypeToString(promo_type_); | 274 LOG(ERROR) << "Malformed JSON: not " << PromoTypeToString(promo_type_); |
| 240 return; | 275 return; |
| 241 } | 276 } |
| 242 | 277 |
| 243 // No support for multiple promos yet. Only consider the first one. | 278 // No support for multiple promos yet. Only consider the first one. |
| 244 const DictionaryValue* promo = NULL; | 279 const DictionaryValue* promo = NULL; |
| 245 if (!promo_list->GetDictionary(0, &promo)) | 280 if (!promo_list->GetDictionary(0, &promo)) |
| 246 return; | 281 return; |
| 247 | 282 |
| 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. | 283 // Date. |
| 259 const ListValue* date_list = NULL; | 284 const ListValue* date_list = NULL; |
| 260 if (promo->GetList("date", &date_list)) { | 285 if (promo->GetList("date", &date_list)) { |
| 261 const DictionaryValue* date; | 286 const DictionaryValue* date; |
| 262 if (date_list->GetDictionary(0, &date)) { | 287 if (date_list->GetDictionary(0, &date)) { |
| 263 std::string time_str; | 288 std::string time_str; |
| 264 base::Time time; | 289 base::Time time; |
| 265 if (date->GetString("start", &time_str) && | 290 if (date->GetString("start", &time_str) && |
| 266 base::Time::FromString(time_str.c_str(), &time)) { | 291 base::Time::FromString(time_str.c_str(), &time)) { |
| 267 start_ = time.ToDoubleT(); | 292 start_ = time.ToDoubleT(); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 286 grouping->GetInteger("increment_frequency", &time_slice_); | 311 grouping->GetInteger("increment_frequency", &time_slice_); |
| 287 grouping->GetInteger("increment_max", &max_group_); | 312 grouping->GetInteger("increment_max", &max_group_); |
| 288 | 313 |
| 289 DVLOG(1) << "num_groups_ = " << num_groups_ | 314 DVLOG(1) << "num_groups_ = " << num_groups_ |
| 290 << ", initial_segment_ = " << initial_segment_ | 315 << ", initial_segment_ = " << initial_segment_ |
| 291 << ", increment_ = " << increment_ | 316 << ", increment_ = " << increment_ |
| 292 << ", time_slice_ = " << time_slice_ | 317 << ", time_slice_ = " << time_slice_ |
| 293 << ", max_group_ = " << max_group_; | 318 << ", max_group_ = " << max_group_; |
| 294 } | 319 } |
| 295 | 320 |
| 321 // Strings. | |
| 322 const DictionaryValue* strings = NULL; | |
| 323 promo->GetDictionary("strings", &strings); | |
| 324 | |
| 296 // Payload. | 325 // Payload. |
| 297 const DictionaryValue* payload = NULL; | 326 const DictionaryValue* payload = NULL; |
| 298 if (promo->GetDictionary("payload", &payload)) { | 327 if (promo->GetDictionary("payload", &payload)) { |
| 299 payload->GetBoolean("gplus_required", &gplus_required_); | 328 payload->GetBoolean("gplus_required", &gplus_required_); |
| 329 DVLOG(1) << "gplus_required_ = " << gplus_required_; | |
| 300 | 330 |
| 301 DVLOG(1) << "gplus_required_ = " << gplus_required_; | 331 base::Value* ppcopy = deepCopyAndResolveStrings(payload, strings); |
| 332 DCHECK(ppcopy != NULL); | |
|
achuithb
2012/08/17 22:55:12
I think DCHECK(ppcopy) is sufficient.
aruslan
2012/08/20 15:36:53
Done.
| |
| 333 DCHECK(ppcopy->IsType(base::Value::TYPE_DICTIONARY)); | |
|
achuithb
2012/08/17 22:55:12
You might want to combine the DCHECKs like
DCHECK(
aruslan
2012/08/20 15:36:53
Done.
| |
| 334 promo_payload_.reset(static_cast<base::DictionaryValue*>(ppcopy)); | |
| 302 } | 335 } |
| 303 | 336 |
| 337 if (!promo_payload_->GetString("promo_message_short", &promo_text_) && | |
| 338 strings) { | |
| 339 // For compatibility with the legacy desktop version, | |
| 340 // if no |payload.promo_message_short| is specified, | |
| 341 // the first string in |strings| is used. | |
| 342 DictionaryValue::Iterator iter(*strings); | |
| 343 iter.value().GetAsString(&promo_text_); | |
| 344 } | |
| 345 DVLOG(1) << "promo_text_=" << promo_text_; | |
| 346 | |
| 304 promo->GetInteger("max_views", &max_views_); | 347 promo->GetInteger("max_views", &max_views_); |
| 305 DVLOG(1) << "max_views_ " << max_views_; | 348 DVLOG(1) << "max_views_ " << max_views_; |
| 306 | 349 |
| 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(); | 350 CheckForNewNotification(); |
| 357 } | 351 } |
| 358 | 352 |
| 359 void NotificationPromo::CheckForNewNotification() { | 353 void NotificationPromo::CheckForNewNotification() { |
| 360 NotificationPromo old_promo(profile_); | 354 NotificationPromo old_promo(profile_); |
| 361 old_promo.InitFromPrefs(promo_type_); | 355 old_promo.InitFromPrefs(promo_type_); |
| 362 const double old_start = old_promo.start_; | 356 const double old_start = old_promo.start_; |
| 363 const double old_end = old_promo.end_; | 357 const double old_end = old_promo.end_; |
| 364 const std::string old_promo_text = old_promo.promo_text_; | 358 const std::string old_promo_text = old_promo.promo_text_; |
| 365 | 359 |
| 366 new_notification_ = | 360 new_notification_ = |
| 367 old_start != start_ || old_end != end_ || old_promo_text != promo_text_; | 361 old_start != start_ || old_end != end_ || old_promo_text != promo_text_; |
| 368 if (new_notification_) | 362 if (new_notification_) |
| 369 OnNewNotification(); | 363 OnNewNotification(); |
| 370 } | 364 } |
| 371 | 365 |
| 372 void NotificationPromo::OnNewNotification() { | 366 void NotificationPromo::OnNewNotification() { |
| 373 DVLOG(1) << "OnNewNotification"; | 367 DVLOG(1) << "OnNewNotification"; |
| 374 // Create a new promo group. | 368 // Create a new promo group. |
| 375 group_ = base::RandInt(0, num_groups_ - 1); | 369 group_ = base::RandInt(0, num_groups_ - 1); |
| 376 WritePrefs(); | 370 WritePrefs(); |
| 377 } | 371 } |
| 378 | 372 |
| 379 // static | 373 // static |
| 380 void NotificationPromo::RegisterUserPrefs(PrefService* prefs) { | 374 void NotificationPromo::RegisterUserPrefs(PrefService* prefs) { |
| 381 ClearDeprecatedPrefs(prefs); | 375 ClearDeprecatedPrefs(prefs); |
| 382 prefs->RegisterDictionaryPref("promo", | 376 prefs->RegisterDictionaryPref(kPrefPromoObject, |
| 383 new base::DictionaryValue, | 377 new base::DictionaryValue, |
| 384 PrefService::UNSYNCABLE_PREF); | 378 PrefService::UNSYNCABLE_PREF); |
| 385 } | 379 } |
| 386 | 380 |
| 387 void NotificationPromo::WritePrefs() { | 381 void NotificationPromo::WritePrefs() { |
| 388 DVLOG(1) << "WritePrefs"; | 382 DVLOG(1) << "WritePrefs"; |
| 389 base::DictionaryValue* ntp_promo = new base::DictionaryValue; | 383 base::DictionaryValue* ntp_promo = new base::DictionaryValue; |
| 390 ntp_promo->SetString(kPrefPromoText, promo_text_); | 384 ntp_promo->SetString(kPrefPromoText, promo_text_); |
| 391 #if defined(OS_ANDROID) | 385 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_); | 386 ntp_promo->SetDouble(kPrefPromoStart, start_); |
| 398 ntp_promo->SetDouble(kPrefPromoEnd, end_); | 387 ntp_promo->SetDouble(kPrefPromoEnd, end_); |
| 399 | 388 |
| 400 ntp_promo->SetInteger(kPrefPromoNumGroups, num_groups_); | 389 ntp_promo->SetInteger(kPrefPromoNumGroups, num_groups_); |
| 401 ntp_promo->SetInteger(kPrefPromoSegment, initial_segment_); | 390 ntp_promo->SetInteger(kPrefPromoSegment, initial_segment_); |
| 402 ntp_promo->SetInteger(kPrefPromoIncrement, increment_); | 391 ntp_promo->SetInteger(kPrefPromoIncrement, increment_); |
| 403 ntp_promo->SetInteger(kPrefPromoIncrementFrequency, time_slice_); | 392 ntp_promo->SetInteger(kPrefPromoIncrementFrequency, time_slice_); |
| 404 ntp_promo->SetInteger(kPrefPromoIncrementMax, max_group_); | 393 ntp_promo->SetInteger(kPrefPromoIncrementMax, max_group_); |
| 405 | 394 |
| 406 ntp_promo->SetInteger(kPrefPromoMaxViews, max_views_); | 395 ntp_promo->SetInteger(kPrefPromoMaxViews, max_views_); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 430 promo_dict->GetList(PromoTypeToString(promo_type_), &promo_list); | 419 promo_dict->GetList(PromoTypeToString(promo_type_), &promo_list); |
| 431 if (!promo_list) | 420 if (!promo_list) |
| 432 return; | 421 return; |
| 433 | 422 |
| 434 const base::DictionaryValue* ntp_promo(NULL); | 423 const base::DictionaryValue* ntp_promo(NULL); |
| 435 promo_list->GetDictionary(0, &ntp_promo); | 424 promo_list->GetDictionary(0, &ntp_promo); |
| 436 if (!ntp_promo) | 425 if (!ntp_promo) |
| 437 return; | 426 return; |
| 438 | 427 |
| 439 ntp_promo->GetString(kPrefPromoText, &promo_text_); | 428 ntp_promo->GetString(kPrefPromoText, &promo_text_); |
| 440 #if defined(OS_ANDROID) | 429 const base::DictionaryValue* dv(NULL); |
|
achuithb
2012/08/17 22:55:12
let's do
const base::DictionaryValue* dv = NULL;
aruslan
2012/08/20 15:36:53
Done.
| |
| 441 ntp_promo->GetString(kPrefPromoTextLong, &promo_text_long_); | 430 if (ntp_promo->GetDictionary(kPrefPromoPayload, &dv)) { |
| 442 ntp_promo->GetString(kPrefPromoActionType, &promo_action_type_); | 431 DCHECK(dv != NULL); |
|
achuithb
2012/08/17 22:55:12
unnecessary
aruslan
2012/08/20 15:36:53
Done.
| |
| 443 const base::ListValue* lv(NULL); | 432 promo_payload_.reset(dv->DeepCopy()); |
| 444 ntp_promo->GetList(kPrefPromoActionArgs, &lv); | 433 } |
| 445 DCHECK(lv != NULL); | |
| 446 promo_action_args_.reset(lv->DeepCopy()); | |
| 447 #endif // defined(OS_ANDROID) | |
| 448 | 434 |
| 449 ntp_promo->GetDouble(kPrefPromoStart, &start_); | 435 ntp_promo->GetDouble(kPrefPromoStart, &start_); |
| 450 ntp_promo->GetDouble(kPrefPromoEnd, &end_); | 436 ntp_promo->GetDouble(kPrefPromoEnd, &end_); |
| 451 | 437 |
| 452 ntp_promo->GetInteger(kPrefPromoNumGroups, &num_groups_); | 438 ntp_promo->GetInteger(kPrefPromoNumGroups, &num_groups_); |
| 453 ntp_promo->GetInteger(kPrefPromoSegment, &initial_segment_); | 439 ntp_promo->GetInteger(kPrefPromoSegment, &initial_segment_); |
| 454 ntp_promo->GetInteger(kPrefPromoIncrement, &increment_); | 440 ntp_promo->GetInteger(kPrefPromoIncrement, &increment_); |
| 455 ntp_promo->GetInteger(kPrefPromoIncrementFrequency, &time_slice_); | 441 ntp_promo->GetInteger(kPrefPromoIncrementFrequency, &time_slice_); |
| 456 ntp_promo->GetInteger(kPrefPromoIncrementMax, &max_group_); | 442 ntp_promo->GetInteger(kPrefPromoIncrementMax, &max_group_); |
| 457 | 443 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 525 if (group_ < initial_segment_) | 511 if (group_ < initial_segment_) |
| 526 return start_; | 512 return start_; |
| 527 return start_ + | 513 return start_ + |
| 528 std::ceil(static_cast<float>(group_ - initial_segment_ + 1) / increment_) | 514 std::ceil(static_cast<float>(group_ - initial_segment_ + 1) / increment_) |
| 529 * time_slice_; | 515 * time_slice_; |
| 530 } | 516 } |
| 531 | 517 |
| 532 double NotificationPromo::EndTime() const { | 518 double NotificationPromo::EndTime() const { |
| 533 return end_; | 519 return end_; |
| 534 } | 520 } |
| OLD | NEW |