Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: chrome/browser/web_resource/notification_promo.cc

Issue 10860025: Remove promotion-type-specific JSON handling from NotificationPromo (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698