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

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

Issue 6542003: Refactor WebResourceService class, making it more generic. Move all the prom... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Fixing an issue in test Created 9 years, 10 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/web_resource_service.h" 5 #include "chrome/browser/web_resource/web_resource_service.h"
6 6
7 #include <string>
8
9 #include "base/command_line.h" 7 #include "base/command_line.h"
10 #include "base/file_path.h" 8 #include "base/file_path.h"
11 #include "base/string_util.h" 9 #include "base/string_util.h"
12 #include "base/string_number_conversions.h" 10 #include "base/string_number_conversions.h"
13 #include "base/threading/thread_restrictions.h" 11 #include "base/threading/thread_restrictions.h"
14 #include "base/time.h" 12 #include "base/time.h"
15 #include "base/utf_string_conversions.h" 13 #include "base/utf_string_conversions.h"
16 #include "base/values.h" 14 #include "base/values.h"
17 #include "chrome/browser/browser_process.h" 15 #include "chrome/browser/browser_process.h"
18 #include "chrome/browser/browser_thread.h" 16 #include "chrome/browser/browser_thread.h"
19 #include "chrome/browser/extensions/extension_service.h" 17 #include "chrome/browser/prefs/pref_service.h"
20 #include "chrome/browser/platform_util.h"
21 #include "chrome/browser/profiles/profile.h" 18 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/sync/sync_ui_util.h" 19 #include "chrome/browser/sync/sync_ui_util.h"
23 #include "chrome/common/chrome_switches.h" 20 #include "chrome/common/chrome_switches.h"
24 #include "chrome/common/extensions/extension.h" 21 #include "chrome/common/extensions/extension.h"
25 #include "chrome/common/net/url_fetcher.h" 22 #include "chrome/common/net/url_fetcher.h"
26 #include "chrome/common/notification_service.h" 23 #include "chrome/common/notification_service.h"
27 #include "chrome/common/notification_type.h" 24 #include "chrome/common/web_resource/web_resource_unpacker.h"
28 #include "chrome/common/pref_names.h"
29 #include "googleurl/src/gurl.h" 25 #include "googleurl/src/gurl.h"
30 #include "net/base/load_flags.h" 26 #include "net/base/load_flags.h"
31 #include "net/url_request/url_request_status.h" 27 #include "net/url_request/url_request_status.h"
32 28
33 namespace {
34
35 // Delay on first fetch so we don't interfere with startup.
36 static const int kStartResourceFetchDelay = 5000;
37
38 // Delay between calls to update the cache (48 hours).
39 static const int kCacheUpdateDelay = 48 * 60 * 60 * 1000;
40
41 // Users are randomly assigned to one of kNTPPromoGroupSize buckets, in order
42 // to be able to roll out promos slowly, or display different promos to
43 // different groups.
44 static const int kNTPPromoGroupSize = 16;
45
46 // Maximum number of hours for each time slice (4 weeks).
47 static const int kMaxTimeSliceHours = 24 * 7 * 4;
48
49 // Used to determine which build type should be shown a given promo.
50 enum BuildType {
51 DEV_BUILD = 1,
52 BETA_BUILD = 1 << 1,
53 STABLE_BUILD = 1 << 2,
54 };
55
56 } // namespace
57
58 const char* WebResourceService::kCurrentTipPrefName = "current_tip";
59 const char* WebResourceService::kTipCachePrefName = "tips";
60
61 class WebResourceService::WebResourceFetcher 29 class WebResourceService::WebResourceFetcher
62 : public URLFetcher::Delegate { 30 : public URLFetcher::Delegate {
63 public: 31 public:
64 explicit WebResourceFetcher(WebResourceService* web_resource_service) : 32 explicit WebResourceFetcher(WebResourceService* web_resource_service) :
65 ALLOW_THIS_IN_INITIALIZER_LIST(fetcher_factory_(this)), 33 ALLOW_THIS_IN_INITIALIZER_LIST(fetcher_factory_(this)),
66 web_resource_service_(web_resource_service) { 34 web_resource_service_(web_resource_service) {
67 } 35 }
68 36
69 // Delay initial load of resource data into cache so as not to interfere 37 // Delay initial load of resource data into cache so as not to interfere
70 // with startup time. 38 // with startup time.
71 void StartAfterDelay(int64 delay_ms) { 39 void StartAfterDelay(int64 delay_ms) {
72 MessageLoop::current()->PostDelayedTask(FROM_HERE, 40 MessageLoop::current()->PostDelayedTask(FROM_HERE,
73 fetcher_factory_.NewRunnableMethod(&WebResourceFetcher::StartFetch), 41 fetcher_factory_.NewRunnableMethod(&WebResourceFetcher::StartFetch),
74 delay_ms); 42 delay_ms);
75 } 43 }
76 44
77 // Initializes the fetching of data from the resource server. Data 45 // Initializes the fetching of data from the resource server. Data
78 // load calls OnURLFetchComplete. 46 // load calls OnURLFetchComplete.
79 void StartFetch() { 47 void StartFetch() {
80 // Balanced in OnURLFetchComplete. 48 // Balanced in OnURLFetchComplete.
81 web_resource_service_->AddRef(); 49 web_resource_service_->AddRef();
82 // First, put our next cache load on the MessageLoop. 50 // First, put our next cache load on the MessageLoop.
83 MessageLoop::current()->PostDelayedTask(FROM_HERE, 51 MessageLoop::current()->PostDelayedTask(FROM_HERE,
84 fetcher_factory_.NewRunnableMethod(&WebResourceFetcher::StartFetch), 52 fetcher_factory_.NewRunnableMethod(&WebResourceFetcher::StartFetch),
85 web_resource_service_->cache_update_delay()); 53 web_resource_service_->cache_update_delay_);
86 // If we are still fetching data, exit. 54 // If we are still fetching data, exit.
87 if (web_resource_service_->in_fetch_) 55 if (web_resource_service_->in_fetch_)
88 return; 56 return;
89 else 57 else
90 web_resource_service_->in_fetch_ = true; 58 web_resource_service_->in_fetch_ = true;
91 59
92 std::string locale = g_browser_process->GetApplicationLocale(); 60 std::string web_resource_server =
93 std::string web_resource_server = kDefaultWebResourceServer; 61 web_resource_service_->web_resource_server_;
94 web_resource_server.append(locale); 62 if (web_resource_service_->apply_locale_to_url_) {
63 std::string locale = g_browser_process->GetApplicationLocale();
64 web_resource_server.append(locale);
65 }
95 66
96 url_fetcher_.reset(new URLFetcher(GURL( 67 url_fetcher_.reset(new URLFetcher(GURL(
97 web_resource_server), 68 web_resource_server),
98 URLFetcher::GET, this)); 69 URLFetcher::GET, this));
99 // Do not let url fetcher affect existing state in profile (by setting 70 // Do not let url fetcher affect existing state in profile (by setting
100 // cookies, for example. 71 // cookies, for example.
101 url_fetcher_->set_load_flags(net::LOAD_DISABLE_CACHE | 72 url_fetcher_->set_load_flags(net::LOAD_DISABLE_CACHE |
102 net::LOAD_DO_NOT_SAVE_COOKIES); 73 net::LOAD_DO_NOT_SAVE_COOKIES);
103 URLRequestContextGetter* url_request_context_getter = 74 URLRequestContextGetter* url_request_context_getter =
104 web_resource_service_->profile()->GetRequestContext(); 75 web_resource_service_->profile_->GetRequestContext();
105 url_fetcher_->set_request_context(url_request_context_getter); 76 url_fetcher_->set_request_context(url_request_context_getter);
106 url_fetcher_->Start(); 77 url_fetcher_->Start();
107 } 78 }
108 79
109 // From URLFetcher::Delegate. 80 // From URLFetcher::Delegate.
110 void OnURLFetchComplete(const URLFetcher* source, 81 void OnURLFetchComplete(const URLFetcher* source,
111 const GURL& url, 82 const GURL& url,
112 const net::URLRequestStatus& status, 83 const net::URLRequestStatus& status,
113 int response_code, 84 int response_code,
114 const ResponseCookies& cookies, 85 const ResponseCookies& cookies,
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 scoped_refptr<WebResourceService> web_resource_service_; 189 scoped_refptr<WebResourceService> web_resource_service_;
219 190
220 // Holds raw JSON string. 191 // Holds raw JSON string.
221 const std::string& json_data_; 192 const std::string& json_data_;
222 193
223 // True if we got a response from the utility process and have cleaned up 194 // True if we got a response from the utility process and have cleaned up
224 // already. 195 // already.
225 bool got_response_; 196 bool got_response_;
226 }; 197 };
227 198
228 // Server for dynamically loaded NTP HTML elements. TODO(mirandac): append 199 WebResourceService::WebResourceService(
229 // locale for future usage, when we're serving localizable strings. 200 Profile* profile,
230 const char* WebResourceService::kDefaultWebResourceServer = 201 const char* web_resource_server,
231 "https://www.google.com/support/chrome/bin/topic/1142433/inproduct?hl="; 202 bool apply_locale_to_url,
232 203 NotificationType::Type notification_type,
233 WebResourceService::WebResourceService(Profile* profile) 204 const char* last_update_time_pref_name,
234 : prefs_(profile->GetPrefs()), 205 int start_fetch_delay,
235 profile_(profile), 206 int cache_update_delay)
207 : profile_(profile),
236 ALLOW_THIS_IN_INITIALIZER_LIST(service_factory_(this)), 208 ALLOW_THIS_IN_INITIALIZER_LIST(service_factory_(this)),
237 in_fetch_(false), 209 in_fetch_(false),
210 web_resource_server_(web_resource_server),
211 apply_locale_to_url_(apply_locale_to_url),
212 notification_type_(notification_type),
213 last_update_time_pref_name_(last_update_time_pref_name),
214 start_fetch_delay_(start_fetch_delay),
215 cache_update_delay_(cache_update_delay),
238 web_resource_update_scheduled_(false) { 216 web_resource_update_scheduled_(false) {
239 Init(); 217 DCHECK(profile);
218 prefs_ = profile_->GetPrefs();
219 resource_dispatcher_host_ = g_browser_process->resource_dispatcher_host();
220 web_resource_fetcher_.reset(new WebResourceFetcher(this));
240 } 221 }
241 222
242 WebResourceService::~WebResourceService() { } 223 WebResourceService::~WebResourceService() { }
243 224
244 void WebResourceService::Init() { 225 void WebResourceService::PostNotification(int64 delay_ms) {
245 cache_update_delay_ = kCacheUpdateDelay; 226 if (web_resource_update_scheduled_)
246 resource_dispatcher_host_ = g_browser_process->resource_dispatcher_host(); 227 return;
247 web_resource_fetcher_.reset(new WebResourceFetcher(this)); 228 if (delay_ms > 0) {
248 prefs_->RegisterStringPref(prefs::kNTPWebResourceCacheUpdate, "0"); 229 web_resource_update_scheduled_ = true;
249 prefs_->RegisterDoublePref(prefs::kNTPCustomLogoStart, 0); 230 MessageLoop::current()->PostDelayedTask(FROM_HERE,
250 prefs_->RegisterDoublePref(prefs::kNTPCustomLogoEnd, 0); 231 service_factory_.NewRunnableMethod(
251 prefs_->RegisterDoublePref(prefs::kNTPPromoStart, 0); 232 &WebResourceService::WebResourceStateChange), delay_ms);
252 prefs_->RegisterDoublePref(prefs::kNTPPromoEnd, 0); 233 } else if (delay_ms == 0) {
253 prefs_->RegisterStringPref(prefs::kNTPPromoLine, std::string()); 234 WebResourceStateChange();
254 prefs_->RegisterBooleanPref(prefs::kNTPPromoClosed, false); 235 }
255 prefs_->RegisterIntegerPref(prefs::kNTPPromoGroup, -1);
256 prefs_->RegisterIntegerPref(prefs::kNTPPromoBuild,
257 DEV_BUILD | BETA_BUILD | STABLE_BUILD);
258 prefs_->RegisterIntegerPref(prefs::kNTPPromoGroupTimeSlice, 0);
259
260 // If the promo start is in the future, set a notification task to invalidate
261 // the NTP cache at the time of the promo start.
262 double promo_start = prefs_->GetDouble(prefs::kNTPPromoStart);
263 double promo_end = prefs_->GetDouble(prefs::kNTPPromoEnd);
264 ScheduleNotification(promo_start, promo_end);
265 } 236 }
266 237
267 void WebResourceService::EndFetch() { 238 void WebResourceService::EndFetch() {
268 in_fetch_ = false; 239 in_fetch_ = false;
269 } 240 }
270 241
271 void WebResourceService::OnWebResourceUnpacked( 242 void WebResourceService::OnWebResourceUnpacked(
272 const DictionaryValue& parsed_json) { 243 const DictionaryValue& parsed_json) {
273 UnpackLogoSignal(parsed_json); 244 Unpack(parsed_json);
274 UnpackPromoSignal(parsed_json);
275 EndFetch(); 245 EndFetch();
276 } 246 }
277 247
278 void WebResourceService::WebResourceStateChange() { 248 void WebResourceService::WebResourceStateChange() {
279 web_resource_update_scheduled_ = false; 249 web_resource_update_scheduled_ = false;
280 NotificationService* service = NotificationService::current(); 250 NotificationService* service = NotificationService::current();
281 service->Notify(NotificationType::WEB_RESOURCE_STATE_CHANGED, 251 service->Notify(notification_type_,
282 Source<WebResourceService>(this), 252 Source<WebResourceService>(this),
283 NotificationService::NoDetails()); 253 NotificationService::NoDetails());
284 } 254 }
285 255
286 void WebResourceService::ScheduleNotification(double promo_start,
287 double promo_end) {
288 if (promo_start > 0 && promo_end > 0 && !web_resource_update_scheduled_) {
289 int64 ms_until_start =
290 static_cast<int64>((base::Time::FromDoubleT(
291 promo_start) - base::Time::Now()).InMilliseconds());
292 int64 ms_until_end =
293 static_cast<int64>((base::Time::FromDoubleT(
294 promo_end) - base::Time::Now()).InMilliseconds());
295 if (ms_until_start > 0) {
296 web_resource_update_scheduled_ = true;
297 MessageLoop::current()->PostDelayedTask(FROM_HERE,
298 service_factory_.NewRunnableMethod(
299 &WebResourceService::WebResourceStateChange),
300 ms_until_start);
301 }
302 if (ms_until_end > 0) {
303 web_resource_update_scheduled_ = true;
304 MessageLoop::current()->PostDelayedTask(FROM_HERE,
305 service_factory_.NewRunnableMethod(
306 &WebResourceService::WebResourceStateChange),
307 ms_until_end);
308 if (ms_until_start <= 0) {
309 // Notify immediately if time is between start and end.
310 WebResourceStateChange();
311 }
312 }
313 }
314 }
315
316 void WebResourceService::StartAfterDelay() { 256 void WebResourceService::StartAfterDelay() {
317 int64 delay = kStartResourceFetchDelay; 257 int64 delay = start_fetch_delay_;
318 // Check whether we have ever put a value in the web resource cache; 258 // Check whether we have ever put a value in the web resource cache;
319 // if so, pull it out and see if it's time to update again. 259 // if so, pull it out and see if it's time to update again.
320 if (prefs_->HasPrefPath(prefs::kNTPWebResourceCacheUpdate)) { 260 if (prefs_->HasPrefPath(last_update_time_pref_name_)) {
321 std::string last_update_pref = 261 std::string last_update_pref =
322 prefs_->GetString(prefs::kNTPWebResourceCacheUpdate); 262 prefs_->GetString(last_update_time_pref_name_);
323 if (!last_update_pref.empty()) { 263 if (!last_update_pref.empty()) {
324 double last_update_value; 264 double last_update_value;
325 base::StringToDouble(last_update_pref, &last_update_value); 265 base::StringToDouble(last_update_pref, &last_update_value);
326 int64 ms_until_update = cache_update_delay_ - 266 int64 ms_until_update = cache_update_delay_ -
327 static_cast<int64>((base::Time::Now() - base::Time::FromDoubleT( 267 static_cast<int64>((base::Time::Now() - base::Time::FromDoubleT(
328 last_update_value)).InMilliseconds()); 268 last_update_value)).InMilliseconds());
329 delay = ms_until_update > cache_update_delay_ ? 269 delay = ms_until_update > cache_update_delay_ ?
330 cache_update_delay_ : (ms_until_update < kStartResourceFetchDelay ? 270 cache_update_delay_ : (ms_until_update < start_fetch_delay_ ?
331 kStartResourceFetchDelay : ms_until_update); 271 start_fetch_delay_ : ms_until_update);
332 } 272 }
333 } 273 }
334 // Start fetch and wait for UpdateResourceCache. 274 // Start fetch and wait for UpdateResourceCache.
335 web_resource_fetcher_->StartAfterDelay(delay); 275 web_resource_fetcher_->StartAfterDelay(delay);
336 } 276 }
337 277
338 void WebResourceService::UpdateResourceCache(const std::string& json_data) { 278 void WebResourceService::UpdateResourceCache(const std::string& json_data) {
339 UnpackerClient* client = new UnpackerClient(this, json_data); 279 UnpackerClient* client = new UnpackerClient(this, json_data);
340 client->Start(); 280 client->Start();
341 281
342 // Set cache update time in preferences. 282 // Set cache update time in preferences.
343 prefs_->SetString(prefs::kNTPWebResourceCacheUpdate, 283 prefs_->SetString(last_update_time_pref_name_,
344 base::DoubleToString(base::Time::Now().ToDoubleT())); 284 base::DoubleToString(base::Time::Now().ToDoubleT()));
345 } 285 }
346
347 void WebResourceService::UnpackTips(const DictionaryValue& parsed_json) {
348 // Get dictionary of cached preferences.
349 web_resource_cache_ =
350 prefs_->GetMutableDictionary(prefs::kNTPWebResourceCache);
351
352 // The list of individual tips.
353 ListValue* tip_holder = new ListValue();
354 web_resource_cache_->Set(WebResourceService::kTipCachePrefName, tip_holder);
355
356 DictionaryValue* topic_dict;
357 ListValue* answer_list;
358 std::string topic_id;
359 std::string answer_id;
360 std::string inproduct;
361 int tip_counter = 0;
362
363 if (parsed_json.GetDictionary("topic", &topic_dict)) {
364 if (topic_dict->GetString("topic_id", &topic_id))
365 web_resource_cache_->SetString("topic_id", topic_id);
366 if (topic_dict->GetList("answers", &answer_list)) {
367 for (ListValue::const_iterator tip_iter = answer_list->begin();
368 tip_iter != answer_list->end(); ++tip_iter) {
369 if (!(*tip_iter)->IsType(Value::TYPE_DICTIONARY))
370 continue;
371 DictionaryValue* a_dic =
372 static_cast<DictionaryValue*>(*tip_iter);
373 if (a_dic->GetString("inproduct", &inproduct)) {
374 tip_holder->Append(Value::CreateStringValue(inproduct));
375 }
376 tip_counter++;
377 }
378 // If tips exist, set current index to 0.
379 if (!inproduct.empty()) {
380 web_resource_cache_->SetInteger(
381 WebResourceService::kCurrentTipPrefName, 0);
382 }
383 }
384 }
385 }
386
387 void WebResourceService::UnpackPromoSignal(const DictionaryValue& parsed_json) {
388 DictionaryValue* topic_dict;
389 ListValue* answer_list;
390 double old_promo_start = 0;
391 double old_promo_end = 0;
392 double promo_start = 0;
393 double promo_end = 0;
394
395 // Check for preexisting start and end values.
396 if (prefs_->HasPrefPath(prefs::kNTPPromoStart) &&
397 prefs_->HasPrefPath(prefs::kNTPPromoEnd)) {
398 old_promo_start = prefs_->GetDouble(prefs::kNTPPromoStart);
399 old_promo_end = prefs_->GetDouble(prefs::kNTPPromoEnd);
400 }
401
402 // Check for newly received start and end values.
403 if (parsed_json.GetDictionary("topic", &topic_dict)) {
404 if (topic_dict->GetList("answers", &answer_list)) {
405 std::string promo_start_string = "";
406 std::string promo_end_string = "";
407 std::string promo_string = "";
408 std::string promo_build = "";
409 int promo_build_type = 0;
410 int time_slice_hrs = 0;
411 for (ListValue::const_iterator tip_iter = answer_list->begin();
412 tip_iter != answer_list->end(); ++tip_iter) {
413 if (!(*tip_iter)->IsType(Value::TYPE_DICTIONARY))
414 continue;
415 DictionaryValue* a_dic =
416 static_cast<DictionaryValue*>(*tip_iter);
417 std::string promo_signal;
418 if (a_dic->GetString("name", &promo_signal)) {
419 if (promo_signal == "promo_start") {
420 a_dic->GetString("question", &promo_build);
421 size_t split = promo_build.find(":");
422 if (split != std::string::npos &&
423 base::StringToInt(promo_build.substr(0, split),
424 &promo_build_type) &&
425 base::StringToInt(promo_build.substr(split+1),
426 &time_slice_hrs) &&
427 promo_build_type >= 0 &&
428 promo_build_type <= (DEV_BUILD | BETA_BUILD | STABLE_BUILD) &&
429 time_slice_hrs >= 0 &&
430 time_slice_hrs <= kMaxTimeSliceHours) {
431 prefs_->SetInteger(prefs::kNTPPromoBuild, promo_build_type);
432 prefs_->SetInteger(prefs::kNTPPromoGroupTimeSlice,
433 time_slice_hrs);
434 } else {
435 // If no time data or bad time data are set, show promo on all
436 // builds with no time slicing.
437 prefs_->SetInteger(prefs::kNTPPromoBuild,
438 DEV_BUILD | BETA_BUILD | STABLE_BUILD);
439 prefs_->SetInteger(prefs::kNTPPromoGroupTimeSlice, 0);
440 }
441 a_dic->GetString("inproduct", &promo_start_string);
442 a_dic->GetString("tooltip", &promo_string);
443 prefs_->SetString(prefs::kNTPPromoLine, promo_string);
444 srand(static_cast<uint32>(time(NULL)));
445 prefs_->SetInteger(prefs::kNTPPromoGroup,
446 rand() % kNTPPromoGroupSize);
447 } else if (promo_signal == "promo_end") {
448 a_dic->GetString("inproduct", &promo_end_string);
449 }
450 }
451 }
452 if (!promo_start_string.empty() &&
453 promo_start_string.length() > 0 &&
454 !promo_end_string.empty() &&
455 promo_end_string.length() > 0) {
456 base::Time start_time;
457 base::Time end_time;
458 if (base::Time::FromString(
459 ASCIIToWide(promo_start_string).c_str(), &start_time) &&
460 base::Time::FromString(
461 ASCIIToWide(promo_end_string).c_str(), &end_time)) {
462 // Add group time slice, adjusted from hours to seconds.
463 promo_start = start_time.ToDoubleT() +
464 (prefs_->FindPreference(prefs::kNTPPromoGroup) ?
465 prefs_->GetInteger(prefs::kNTPPromoGroup) *
466 time_slice_hrs * 60 * 60 : 0);
467 promo_end = end_time.ToDoubleT();
468 }
469 }
470 }
471 }
472
473 // If start or end times have changed, trigger a new web resource
474 // notification, so that the logo on the NTP is updated. This check is
475 // outside the reading of the web resource data, because the absence of
476 // dates counts as a triggering change if there were dates before.
477 // Also reset the promo closed preference, to signal a new promo.
478 if (!(old_promo_start == promo_start) ||
479 !(old_promo_end == promo_end)) {
480 prefs_->SetDouble(prefs::kNTPPromoStart, promo_start);
481 prefs_->SetDouble(prefs::kNTPPromoEnd, promo_end);
482 prefs_->SetBoolean(prefs::kNTPPromoClosed, false);
483 ScheduleNotification(promo_start, promo_end);
484 }
485 }
486
487 void WebResourceService::UnpackLogoSignal(const DictionaryValue& parsed_json) {
488 DictionaryValue* topic_dict;
489 ListValue* answer_list;
490 double old_logo_start = 0;
491 double old_logo_end = 0;
492 double logo_start = 0;
493 double logo_end = 0;
494
495 // Check for preexisting start and end values.
496 if (prefs_->HasPrefPath(prefs::kNTPCustomLogoStart) &&
497 prefs_->HasPrefPath(prefs::kNTPCustomLogoEnd)) {
498 old_logo_start = prefs_->GetDouble(prefs::kNTPCustomLogoStart);
499 old_logo_end = prefs_->GetDouble(prefs::kNTPCustomLogoEnd);
500 }
501
502 // Check for newly received start and end values.
503 if (parsed_json.GetDictionary("topic", &topic_dict)) {
504 if (topic_dict->GetList("answers", &answer_list)) {
505 std::string logo_start_string = "";
506 std::string logo_end_string = "";
507 for (ListValue::const_iterator tip_iter = answer_list->begin();
508 tip_iter != answer_list->end(); ++tip_iter) {
509 if (!(*tip_iter)->IsType(Value::TYPE_DICTIONARY))
510 continue;
511 DictionaryValue* a_dic =
512 static_cast<DictionaryValue*>(*tip_iter);
513 std::string logo_signal;
514 if (a_dic->GetString("name", &logo_signal)) {
515 if (logo_signal == "custom_logo_start") {
516 a_dic->GetString("inproduct", &logo_start_string);
517 } else if (logo_signal == "custom_logo_end") {
518 a_dic->GetString("inproduct", &logo_end_string);
519 }
520 }
521 }
522 if (!logo_start_string.empty() &&
523 logo_start_string.length() > 0 &&
524 !logo_end_string.empty() &&
525 logo_end_string.length() > 0) {
526 base::Time start_time;
527 base::Time end_time;
528 if (base::Time::FromString(
529 ASCIIToWide(logo_start_string).c_str(), &start_time) &&
530 base::Time::FromString(
531 ASCIIToWide(logo_end_string).c_str(), &end_time)) {
532 logo_start = start_time.ToDoubleT();
533 logo_end = end_time.ToDoubleT();
534 }
535 }
536 }
537 }
538
539 // If logo start or end times have changed, trigger a new web resource
540 // notification, so that the logo on the NTP is updated. This check is
541 // outside the reading of the web resource data, because the absence of
542 // dates counts as a triggering change if there were dates before.
543 if (!(old_logo_start == logo_start) ||
544 !(old_logo_end == logo_end)) {
545 prefs_->SetDouble(prefs::kNTPCustomLogoStart, logo_start);
546 prefs_->SetDouble(prefs::kNTPCustomLogoEnd, logo_end);
547 NotificationService* service = NotificationService::current();
548 service->Notify(NotificationType::WEB_RESOURCE_STATE_CHANGED,
549 Source<WebResourceService>(this),
550 NotificationService::NoDetails());
551 }
552 }
553
554 namespace WebResourceServiceUtil {
555
556 bool CanShowPromo(Profile* profile) {
557 bool promo_closed = false;
558 PrefService* prefs = profile->GetPrefs();
559 if (prefs->HasPrefPath(prefs::kNTPPromoClosed))
560 promo_closed = prefs->GetBoolean(prefs::kNTPPromoClosed);
561
562 // Only show if not synced.
563 bool is_synced =
564 (profile->HasProfileSyncService() &&
565 sync_ui_util::GetStatus(
566 profile->GetProfileSyncService()) == sync_ui_util::SYNCED);
567
568 // GetVersionStringModifier hits the registry. See http://crbug.com/70898.
569 base::ThreadRestrictions::ScopedAllowIO allow_io;
570 const std::string channel = platform_util::GetVersionStringModifier();
571 bool is_promo_build = false;
572 if (prefs->HasPrefPath(prefs::kNTPPromoBuild)) {
573 int builds_allowed = prefs->GetInteger(prefs::kNTPPromoBuild);
574 if (channel == "dev") {
575 is_promo_build = (DEV_BUILD & builds_allowed) != 0;
576 } else if (channel == "beta") {
577 is_promo_build = (BETA_BUILD & builds_allowed) != 0;
578 } else if (channel == "stable") {
579 is_promo_build = (STABLE_BUILD & builds_allowed) != 0;
580 } else {
581 is_promo_build = true;
582 }
583 }
584
585 return !promo_closed && !is_synced && is_promo_build;
586 }
587
588 } // namespace WebResourceService
589
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698