diff options
author | zmo@google.com <zmo@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-18 17:54:48 +0000 |
---|---|---|
committer | zmo@google.com <zmo@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-18 17:54:48 +0000 |
commit | 92c699d5a6b73316cb9fd7f44ef9753038b02846 (patch) | |
tree | d252157e33f107736619be082422fd753a3956e1 /chrome/browser/web_resource | |
parent | c63248d4041385f117c09a47cee79415396193c5 (diff) | |
download | chromium_src-92c699d5a6b73316cb9fd7f44ef9753038b02846.zip chromium_src-92c699d5a6b73316cb9fd7f44ef9753038b02846.tar.gz chromium_src-92c699d5a6b73316cb9fd7f44ef9753038b02846.tar.bz2 |
Refactor WebResourceService class, making it more generic. Move all the promo-related code into a new PromoResourceService class that inherits WebResourceService.
This refactoring will allow us to re-use WebResourceService class for GPU Blacklist updates purpose.
This CL tries to minimize the code change and adds no new logic.
BUG=68802
TEST=unittest,promo functions working fine as before.
Review URL: http://codereview.chromium.org/6542003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@75403 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/web_resource')
-rw-r--r-- | chrome/browser/web_resource/promo_resource_service.cc | 358 | ||||
-rw-r--r-- | chrome/browser/web_resource/promo_resource_service.h | 149 | ||||
-rw-r--r-- | chrome/browser/web_resource/promo_resource_service_unittest.cc (renamed from chrome/browser/web_resource/web_resource_service_unittest.cc) | 24 | ||||
-rw-r--r-- | chrome/browser/web_resource/web_resource_service.cc | 406 | ||||
-rw-r--r-- | chrome/browser/web_resource/web_resource_service.h | 180 |
5 files changed, 610 insertions, 507 deletions
diff --git a/chrome/browser/web_resource/promo_resource_service.cc b/chrome/browser/web_resource/promo_resource_service.cc new file mode 100644 index 0000000..f694563 --- /dev/null +++ b/chrome/browser/web_resource/promo_resource_service.cc @@ -0,0 +1,358 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/web_resource/promo_resource_service.h" + +#include "base/string_number_conversions.h" +#include "base/threading/thread_restrictions.h" +#include "base/time.h" +#include "base/values.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/browser_thread.h" +#include "chrome/browser/platform_util.h" +#include "chrome/browser/prefs/pref_service.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/sync/sync_ui_util.h" +#include "chrome/common/notification_service.h" +#include "chrome/common/notification_type.h" +#include "chrome/common/pref_names.h" + +namespace { + +// Delay on first fetch so we don't interfere with startup. +static const int kStartResourceFetchDelay = 5000; + +// Delay between calls to update the cache (48 hours). +static const int kCacheUpdateDelay = 48 * 60 * 60 * 1000; + +// Users are randomly assigned to one of kNTPPromoGroupSize buckets, in order +// to be able to roll out promos slowly, or display different promos to +// different groups. +static const int kNTPPromoGroupSize = 16; + +// Maximum number of hours for each time slice (4 weeks). +static const int kMaxTimeSliceHours = 24 * 7 * 4; + +// Used to determine which build type should be shown a given promo. +enum BuildType { + DEV_BUILD = 1, + BETA_BUILD = 1 << 1, + STABLE_BUILD = 1 << 2, +}; + +} // namespace + +const char* PromoResourceService::kCurrentTipPrefName = "current_tip"; +const char* PromoResourceService::kTipCachePrefName = "tips"; + +// Server for dynamically loaded NTP HTML elements. TODO(mirandac): append +// locale for future usage, when we're serving localizable strings. +const char* PromoResourceService::kDefaultPromoResourceServer = + "https://www.google.com/support/chrome/bin/topic/1142433/inproduct?hl="; + +PromoResourceService::PromoResourceService(Profile* profile) + : WebResourceService(profile, + PromoResourceService::kDefaultPromoResourceServer, + true, // append locale to URL + NotificationType::PROMO_RESOURCE_STATE_CHANGED, + prefs::kNTPPromoResourceCacheUpdate, + kStartResourceFetchDelay, + kCacheUpdateDelay), + web_resource_cache_(NULL) { + Init(); +} + +PromoResourceService::~PromoResourceService() { } + +void PromoResourceService::Init() { + prefs_->RegisterStringPref(prefs::kNTPPromoResourceCacheUpdate, "0"); + prefs_->RegisterDoublePref(prefs::kNTPCustomLogoStart, 0); + prefs_->RegisterDoublePref(prefs::kNTPCustomLogoEnd, 0); + prefs_->RegisterDoublePref(prefs::kNTPPromoStart, 0); + prefs_->RegisterDoublePref(prefs::kNTPPromoEnd, 0); + prefs_->RegisterStringPref(prefs::kNTPPromoLine, std::string()); + prefs_->RegisterBooleanPref(prefs::kNTPPromoClosed, false); + prefs_->RegisterIntegerPref(prefs::kNTPPromoGroup, -1); + prefs_->RegisterIntegerPref(prefs::kNTPPromoBuild, + DEV_BUILD | BETA_BUILD | STABLE_BUILD); + prefs_->RegisterIntegerPref(prefs::kNTPPromoGroupTimeSlice, 0); + + // If the promo start is in the future, set a notification task to invalidate + // the NTP cache at the time of the promo start. + double promo_start = prefs_->GetDouble(prefs::kNTPPromoStart); + double promo_end = prefs_->GetDouble(prefs::kNTPPromoEnd); + ScheduleNotification(promo_start, promo_end); +} + +void PromoResourceService::Unpack(const DictionaryValue& parsed_json) { + UnpackLogoSignal(parsed_json); + UnpackPromoSignal(parsed_json); +} + +void PromoResourceService::ScheduleNotification(double promo_start, + double promo_end) { + if (promo_start > 0 && promo_end > 0) { + int64 ms_until_start = + static_cast<int64>((base::Time::FromDoubleT( + promo_start) - base::Time::Now()).InMilliseconds()); + int64 ms_until_end = + static_cast<int64>((base::Time::FromDoubleT( + promo_end) - base::Time::Now()).InMilliseconds()); + if (ms_until_start > 0) + PostNotification(ms_until_start); + if (ms_until_end > 0) { + PostNotification(ms_until_end); + if (ms_until_start <= 0) { + // Notify immediately if time is between start and end. + PostNotification(0); + } + } + } +} + +void PromoResourceService::UnpackTips(const DictionaryValue& parsed_json) { + // Get dictionary of cached preferences. + web_resource_cache_ = + prefs_->GetMutableDictionary(prefs::kNTPPromoResourceCache); + + // The list of individual tips. + ListValue* tip_holder = new ListValue(); + web_resource_cache_->Set(PromoResourceService::kTipCachePrefName, tip_holder); + + DictionaryValue* topic_dict; + ListValue* answer_list; + std::string topic_id; + std::string answer_id; + std::string inproduct; + int tip_counter = 0; + + if (parsed_json.GetDictionary("topic", &topic_dict)) { + if (topic_dict->GetString("topic_id", &topic_id)) + web_resource_cache_->SetString("topic_id", topic_id); + if (topic_dict->GetList("answers", &answer_list)) { + for (ListValue::const_iterator tip_iter = answer_list->begin(); + tip_iter != answer_list->end(); ++tip_iter) { + if (!(*tip_iter)->IsType(Value::TYPE_DICTIONARY)) + continue; + DictionaryValue* a_dic = + static_cast<DictionaryValue*>(*tip_iter); + if (a_dic->GetString("inproduct", &inproduct)) { + tip_holder->Append(Value::CreateStringValue(inproduct)); + } + tip_counter++; + } + // If tips exist, set current index to 0. + if (!inproduct.empty()) { + web_resource_cache_->SetInteger( + PromoResourceService::kCurrentTipPrefName, 0); + } + } + } +} + +void PromoResourceService::UnpackPromoSignal( + const DictionaryValue& parsed_json) { + DictionaryValue* topic_dict; + ListValue* answer_list; + double old_promo_start = 0; + double old_promo_end = 0; + double promo_start = 0; + double promo_end = 0; + + // Check for preexisting start and end values. + if (prefs_->HasPrefPath(prefs::kNTPPromoStart) && + prefs_->HasPrefPath(prefs::kNTPPromoEnd)) { + old_promo_start = prefs_->GetDouble(prefs::kNTPPromoStart); + old_promo_end = prefs_->GetDouble(prefs::kNTPPromoEnd); + } + + // Check for newly received start and end values. + if (parsed_json.GetDictionary("topic", &topic_dict)) { + if (topic_dict->GetList("answers", &answer_list)) { + std::string promo_start_string = ""; + std::string promo_end_string = ""; + std::string promo_string = ""; + std::string promo_build = ""; + int promo_build_type = 0; + int time_slice_hrs = 0; + for (ListValue::const_iterator tip_iter = answer_list->begin(); + tip_iter != answer_list->end(); ++tip_iter) { + if (!(*tip_iter)->IsType(Value::TYPE_DICTIONARY)) + continue; + DictionaryValue* a_dic = + static_cast<DictionaryValue*>(*tip_iter); + std::string promo_signal; + if (a_dic->GetString("name", &promo_signal)) { + if (promo_signal == "promo_start") { + a_dic->GetString("question", &promo_build); + size_t split = promo_build.find(":"); + if (split != std::string::npos && + base::StringToInt(promo_build.substr(0, split), + &promo_build_type) && + base::StringToInt(promo_build.substr(split+1), + &time_slice_hrs) && + promo_build_type >= 0 && + promo_build_type <= (DEV_BUILD | BETA_BUILD | STABLE_BUILD) && + time_slice_hrs >= 0 && + time_slice_hrs <= kMaxTimeSliceHours) { + prefs_->SetInteger(prefs::kNTPPromoBuild, promo_build_type); + prefs_->SetInteger(prefs::kNTPPromoGroupTimeSlice, + time_slice_hrs); + } else { + // If no time data or bad time data are set, show promo on all + // builds with no time slicing. + prefs_->SetInteger(prefs::kNTPPromoBuild, + DEV_BUILD | BETA_BUILD | STABLE_BUILD); + prefs_->SetInteger(prefs::kNTPPromoGroupTimeSlice, 0); + } + a_dic->GetString("inproduct", &promo_start_string); + a_dic->GetString("tooltip", &promo_string); + prefs_->SetString(prefs::kNTPPromoLine, promo_string); + srand(static_cast<uint32>(time(NULL))); + prefs_->SetInteger(prefs::kNTPPromoGroup, + rand() % kNTPPromoGroupSize); + } else if (promo_signal == "promo_end") { + a_dic->GetString("inproduct", &promo_end_string); + } + } + } + if (!promo_start_string.empty() && + promo_start_string.length() > 0 && + !promo_end_string.empty() && + promo_end_string.length() > 0) { + base::Time start_time; + base::Time end_time; + if (base::Time::FromString( + ASCIIToWide(promo_start_string).c_str(), &start_time) && + base::Time::FromString( + ASCIIToWide(promo_end_string).c_str(), &end_time)) { + // Add group time slice, adjusted from hours to seconds. + promo_start = start_time.ToDoubleT() + + (prefs_->FindPreference(prefs::kNTPPromoGroup) ? + prefs_->GetInteger(prefs::kNTPPromoGroup) * + time_slice_hrs * 60 * 60 : 0); + promo_end = end_time.ToDoubleT(); + } + } + } + } + + // If start or end times have changed, trigger a new web resource + // notification, so that the logo on the NTP is updated. This check is + // outside the reading of the web resource data, because the absence of + // dates counts as a triggering change if there were dates before. + // Also reset the promo closed preference, to signal a new promo. + if (!(old_promo_start == promo_start) || + !(old_promo_end == promo_end)) { + prefs_->SetDouble(prefs::kNTPPromoStart, promo_start); + prefs_->SetDouble(prefs::kNTPPromoEnd, promo_end); + prefs_->SetBoolean(prefs::kNTPPromoClosed, false); + ScheduleNotification(promo_start, promo_end); + } +} + +void PromoResourceService::UnpackLogoSignal( + const DictionaryValue& parsed_json) { + DictionaryValue* topic_dict; + ListValue* answer_list; + double old_logo_start = 0; + double old_logo_end = 0; + double logo_start = 0; + double logo_end = 0; + + // Check for preexisting start and end values. + if (prefs_->HasPrefPath(prefs::kNTPCustomLogoStart) && + prefs_->HasPrefPath(prefs::kNTPCustomLogoEnd)) { + old_logo_start = prefs_->GetDouble(prefs::kNTPCustomLogoStart); + old_logo_end = prefs_->GetDouble(prefs::kNTPCustomLogoEnd); + } + + // Check for newly received start and end values. + if (parsed_json.GetDictionary("topic", &topic_dict)) { + if (topic_dict->GetList("answers", &answer_list)) { + std::string logo_start_string = ""; + std::string logo_end_string = ""; + for (ListValue::const_iterator tip_iter = answer_list->begin(); + tip_iter != answer_list->end(); ++tip_iter) { + if (!(*tip_iter)->IsType(Value::TYPE_DICTIONARY)) + continue; + DictionaryValue* a_dic = + static_cast<DictionaryValue*>(*tip_iter); + std::string logo_signal; + if (a_dic->GetString("name", &logo_signal)) { + if (logo_signal == "custom_logo_start") { + a_dic->GetString("inproduct", &logo_start_string); + } else if (logo_signal == "custom_logo_end") { + a_dic->GetString("inproduct", &logo_end_string); + } + } + } + if (!logo_start_string.empty() && + logo_start_string.length() > 0 && + !logo_end_string.empty() && + logo_end_string.length() > 0) { + base::Time start_time; + base::Time end_time; + if (base::Time::FromString( + ASCIIToWide(logo_start_string).c_str(), &start_time) && + base::Time::FromString( + ASCIIToWide(logo_end_string).c_str(), &end_time)) { + logo_start = start_time.ToDoubleT(); + logo_end = end_time.ToDoubleT(); + } + } + } + } + + // If logo start or end times have changed, trigger a new web resource + // notification, so that the logo on the NTP is updated. This check is + // outside the reading of the web resource data, because the absence of + // dates counts as a triggering change if there were dates before. + if (!(old_logo_start == logo_start) || + !(old_logo_end == logo_end)) { + prefs_->SetDouble(prefs::kNTPCustomLogoStart, logo_start); + prefs_->SetDouble(prefs::kNTPCustomLogoEnd, logo_end); + NotificationService* service = NotificationService::current(); + service->Notify(NotificationType::PROMO_RESOURCE_STATE_CHANGED, + Source<WebResourceService>(this), + NotificationService::NoDetails()); + } +} + +namespace PromoResourceServiceUtil { + +bool CanShowPromo(Profile* profile) { + bool promo_closed = false; + PrefService* prefs = profile->GetPrefs(); + if (prefs->HasPrefPath(prefs::kNTPPromoClosed)) + promo_closed = prefs->GetBoolean(prefs::kNTPPromoClosed); + + // Only show if not synced. + bool is_synced = + (profile->HasProfileSyncService() && + sync_ui_util::GetStatus( + profile->GetProfileSyncService()) == sync_ui_util::SYNCED); + + // GetVersionStringModifier hits the registry. See http://crbug.com/70898. + base::ThreadRestrictions::ScopedAllowIO allow_io; + const std::string channel = platform_util::GetVersionStringModifier(); + bool is_promo_build = false; + if (prefs->HasPrefPath(prefs::kNTPPromoBuild)) { + int builds_allowed = prefs->GetInteger(prefs::kNTPPromoBuild); + if (channel == "dev") { + is_promo_build = (DEV_BUILD & builds_allowed) != 0; + } else if (channel == "beta") { + is_promo_build = (BETA_BUILD & builds_allowed) != 0; + } else if (channel == "stable") { + is_promo_build = (STABLE_BUILD & builds_allowed) != 0; + } else { + is_promo_build = true; + } + } + + return !promo_closed && !is_synced && is_promo_build; +} + +} // namespace PromoResourceServiceUtil + diff --git a/chrome/browser/web_resource/promo_resource_service.h b/chrome/browser/web_resource/promo_resource_service.h new file mode 100644 index 0000000..5f833d6 --- /dev/null +++ b/chrome/browser/web_resource/promo_resource_service.h @@ -0,0 +1,149 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_WEB_RESOURCE_PROMO_RESOURCE_SERVICE_H_ +#define CHROME_BROWSER_WEB_RESOURCE_PROMO_RESOURCE_SERVICE_H_ +#pragma once + +#include "chrome/browser/web_resource/web_resource_service.h" + +namespace PromoResourceServiceUtil { + +// Certain promotions should only be shown to certain classes of users. This +// function will change to reflect each kind of promotion. +bool CanShowPromo(Profile* profile); + +} // namespace PromoResourceServiceUtil + +// A PromoResourceService fetches data from a web resource server to be used to +// dynamically change the appearance of the New Tab Page. For example, it has +// been used to fetch "tips" to be displayed on the NTP, or to display +// promotional messages to certain groups of Chrome users. +// +// TODO(mirandac): Arrange for a server to be set up specifically for promo +// messages, which have until now been piggybacked onto the old tips server +// structure. (see http://crbug.com/70634 for details.) +class PromoResourceService + : public WebResourceService { + public: + explicit PromoResourceService(Profile* profile); + + // Unpack the web resource as a set of tips. Expects json in the form of: + // { + // "lang": "en", + // "topic": { + // "topid_id": "24013", + // "topics": [ + // ], + // "answers": [ + // { + // "answer_id": "18625", + // "inproduct": "Text here will be shown as a tip", + // }, + // ... + // ] + // } + // } + // + // Public for unit testing. + void UnpackTips(const DictionaryValue& parsed_json); + + // Unpack the web resource as a custom promo signal. Expects a start and end + // signal, with the promo to be shown in the tooltip of the start signal + // field. Delivery will be in json in the form of: + // { + // "topic": { + // "answers": [ + // { + // "answer_id": "1067976", + // "name": "promo_start", + // "question": "1:24", + // "tooltip": + // "Click \u003ca href=http://www.google.com\u003ehere\u003c/a\u003e!", + // "inproduct": "10/8/09 12:00", + // "inproduct_target": null + // }, + // { + // "answer_id": "1067976", + // "name": "promo_end", + // "question": "", + // "tooltip": "", + // "inproduct": "10/8/11 12:00", + // "inproduct_target": null + // }, + // ... + // ] + // } + // } + // + // Because the promo signal data is piggybacked onto the tip server, the + // values don't exactly correspond with the field names: + // + // For "promo_start" or "promo_end", the date to start or stop showing the + // promotional line is given by the "inproduct" line. + // For "promo_start", the promotional line itself is given in the "tooltip" + // field. The "question" field gives the type of builds that should be shown + // this promo (see the BuildType enum in web_resource_service.cc) and the + // number of hours that each promo group should see it, separated by ":". + // For example, "7:24" would indicate that all builds should see the promo, + // and each group should see it for 24 hours. + // + // Public for unit testing. + void UnpackPromoSignal(const DictionaryValue& parsed_json); + + // Unpack the promo resource as a custom logo signal. Expects a start and end + // signal. Delivery will be in json in the form of: + // { + // "topic": { + // "answers": [ + // { + // "answer_id": "107366", + // "name": "custom_logo_start", + // "question": "", + // "tooltip": "", + // "inproduct": "10/8/09 12:00", + // "inproduct_target": null + // }, + // { + // "answer_id": "107366", + // "name": "custom_logo_end", + // "question": "", + // "tooltip": "", + // "inproduct": "10/8/09 12:00", + // "inproduct_target": null + // }, + // ... + // ] + // } + // } + // + // Public for unit testing. + void UnpackLogoSignal(const DictionaryValue& parsed_json); + + static const char* kCurrentTipPrefName; + static const char* kTipCachePrefName; + + // Default server of dynamically loaded NTP HTML elements (promotions, tips): + static const char* kDefaultPromoResourceServer; + + private: + virtual ~PromoResourceService(); + + virtual void Unpack(const DictionaryValue& parsed_json); + + void Init(); + + // Schedule a notification that a web resource is either going to become + // available or be no longer valid. + void ScheduleNotification(double ms_start_time, double ms_end_time); + + // Gets mutable dictionary attached to user's preferences, so that we + // can write resource data back to user's pref file. + DictionaryValue* web_resource_cache_; + + DISALLOW_COPY_AND_ASSIGN(PromoResourceService); +}; + +#endif // CHROME_BROWSER_WEB_RESOURCE_PROMO_RESOURCE_SERVICE_H_ + diff --git a/chrome/browser/web_resource/web_resource_service_unittest.cc b/chrome/browser/web_resource/promo_resource_service_unittest.cc index cb51d9f..e84e43b 100644 --- a/chrome/browser/web_resource/web_resource_service_unittest.cc +++ b/chrome/browser/web_resource/promo_resource_service_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -7,16 +7,16 @@ #include "base/utf_string_conversions.h" #include "base/values.h" #include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/web_resource/web_resource_service.h" +#include "chrome/browser/web_resource/promo_resource_service.h" #include "chrome/common/pref_names.h" #include "chrome/test/testing_profile.h" #include "testing/gtest/include/gtest/gtest.h" -typedef testing::Test WebResourceServiceTest; +typedef testing::Test PromoResourceServiceTest; namespace { -// From web_resource_service.cc +// From promo_resource_service.cc enum BuildType { DEV_BUILD = 1, BETA_BUILD = 1 << 1, @@ -27,11 +27,11 @@ enum BuildType { // Verifies that custom dates read from a web resource server are written to // the preferences file. -TEST_F(WebResourceServiceTest, UnpackLogoSignal) { - // Set up a testing profile and create a web resource service. +TEST_F(PromoResourceServiceTest, UnpackLogoSignal) { + // Set up a testing profile and create a promo resource service. TestingProfile profile; - scoped_refptr<WebResourceService> web_resource_service( - new WebResourceService(&profile)); + scoped_refptr<PromoResourceService> web_resource_service( + new PromoResourceService(&profile)); // Set up start and end dates in a Dictionary as if parsed from the service. std::string json = "{ " @@ -109,11 +109,11 @@ TEST_F(WebResourceServiceTest, UnpackLogoSignal) { EXPECT_EQ(logo_end, 0); // date value reset to 0; } -TEST_F(WebResourceServiceTest, UnpackPromoSignal) { - // Set up a testing profile and create a web resource service. +TEST_F(PromoResourceServiceTest, UnpackPromoSignal) { + // Set up a testing profile and create a promo resource service. TestingProfile profile; - scoped_refptr<WebResourceService> web_resource_service( - new WebResourceService(&profile)); + scoped_refptr<PromoResourceService> web_resource_service( + new PromoResourceService(&profile)); // Set up start and end dates and promo line in a Dictionary as if parsed // from the service. diff --git a/chrome/browser/web_resource/web_resource_service.cc b/chrome/browser/web_resource/web_resource_service.cc index dad4343..daddae7 100644 --- a/chrome/browser/web_resource/web_resource_service.cc +++ b/chrome/browser/web_resource/web_resource_service.cc @@ -4,8 +4,6 @@ #include "chrome/browser/web_resource/web_resource_service.h" -#include <string> - #include "base/command_line.h" #include "base/file_path.h" #include "base/string_util.h" @@ -16,48 +14,18 @@ #include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_thread.h" -#include "chrome/browser/extensions/extension_service.h" -#include "chrome/browser/platform_util.h" +#include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/sync_ui_util.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/net/url_fetcher.h" #include "chrome/common/notification_service.h" -#include "chrome/common/notification_type.h" -#include "chrome/common/pref_names.h" +#include "chrome/common/web_resource/web_resource_unpacker.h" #include "googleurl/src/gurl.h" #include "net/base/load_flags.h" #include "net/url_request/url_request_status.h" -namespace { - -// Delay on first fetch so we don't interfere with startup. -static const int kStartResourceFetchDelay = 5000; - -// Delay between calls to update the cache (48 hours). -static const int kCacheUpdateDelay = 48 * 60 * 60 * 1000; - -// Users are randomly assigned to one of kNTPPromoGroupSize buckets, in order -// to be able to roll out promos slowly, or display different promos to -// different groups. -static const int kNTPPromoGroupSize = 16; - -// Maximum number of hours for each time slice (4 weeks). -static const int kMaxTimeSliceHours = 24 * 7 * 4; - -// Used to determine which build type should be shown a given promo. -enum BuildType { - DEV_BUILD = 1, - BETA_BUILD = 1 << 1, - STABLE_BUILD = 1 << 2, -}; - -} // namespace - -const char* WebResourceService::kCurrentTipPrefName = "current_tip"; -const char* WebResourceService::kTipCachePrefName = "tips"; - class WebResourceService::WebResourceFetcher : public URLFetcher::Delegate { public: @@ -70,8 +38,8 @@ class WebResourceService::WebResourceFetcher // with startup time. void StartAfterDelay(int64 delay_ms) { MessageLoop::current()->PostDelayedTask(FROM_HERE, - fetcher_factory_.NewRunnableMethod(&WebResourceFetcher::StartFetch), - delay_ms); + fetcher_factory_.NewRunnableMethod(&WebResourceFetcher::StartFetch), + delay_ms); } // Initializes the fetching of data from the resource server. Data @@ -82,16 +50,19 @@ class WebResourceService::WebResourceFetcher // First, put our next cache load on the MessageLoop. MessageLoop::current()->PostDelayedTask(FROM_HERE, fetcher_factory_.NewRunnableMethod(&WebResourceFetcher::StartFetch), - web_resource_service_->cache_update_delay()); + web_resource_service_->cache_update_delay_); // If we are still fetching data, exit. if (web_resource_service_->in_fetch_) return; else web_resource_service_->in_fetch_ = true; - std::string locale = g_browser_process->GetApplicationLocale(); - std::string web_resource_server = kDefaultWebResourceServer; - web_resource_server.append(locale); + std::string web_resource_server = + web_resource_service_->web_resource_server_; + if (web_resource_service_->apply_locale_to_url_) { + std::string locale = g_browser_process->GetApplicationLocale(); + web_resource_server.append(locale); + } url_fetcher_.reset(new URLFetcher(GURL( web_resource_server), @@ -99,9 +70,9 @@ class WebResourceService::WebResourceFetcher // Do not let url fetcher affect existing state in profile (by setting // cookies, for example. url_fetcher_->set_load_flags(net::LOAD_DISABLE_CACHE | - net::LOAD_DO_NOT_SAVE_COOKIES); + net::LOAD_DO_NOT_SAVE_COOKIES); URLRequestContextGetter* url_request_context_getter = - web_resource_service_->profile()->GetRequestContext(); + web_resource_service_->profile_->GetRequestContext(); url_fetcher_->set_request_context(url_request_context_getter); url_fetcher_->Start(); } @@ -225,43 +196,43 @@ class WebResourceService::UnpackerClient bool got_response_; }; -// Server for dynamically loaded NTP HTML elements. TODO(mirandac): append -// locale for future usage, when we're serving localizable strings. -const char* WebResourceService::kDefaultWebResourceServer = - "https://www.google.com/support/chrome/bin/topic/1142433/inproduct?hl="; - -WebResourceService::WebResourceService(Profile* profile) - : prefs_(profile->GetPrefs()), - profile_(profile), +WebResourceService::WebResourceService( + Profile* profile, + const char* web_resource_server, + bool apply_locale_to_url, + NotificationType::Type notification_type, + const char* last_update_time_pref_name, + int start_fetch_delay, + int cache_update_delay) + : profile_(profile), ALLOW_THIS_IN_INITIALIZER_LIST(service_factory_(this)), in_fetch_(false), + web_resource_server_(web_resource_server), + apply_locale_to_url_(apply_locale_to_url), + notification_type_(notification_type), + last_update_time_pref_name_(last_update_time_pref_name), + start_fetch_delay_(start_fetch_delay), + cache_update_delay_(cache_update_delay), web_resource_update_scheduled_(false) { - Init(); + DCHECK(profile); + prefs_ = profile_->GetPrefs(); + resource_dispatcher_host_ = g_browser_process->resource_dispatcher_host(); + web_resource_fetcher_.reset(new WebResourceFetcher(this)); } WebResourceService::~WebResourceService() { } -void WebResourceService::Init() { - cache_update_delay_ = kCacheUpdateDelay; - resource_dispatcher_host_ = g_browser_process->resource_dispatcher_host(); - web_resource_fetcher_.reset(new WebResourceFetcher(this)); - prefs_->RegisterStringPref(prefs::kNTPWebResourceCacheUpdate, "0"); - prefs_->RegisterDoublePref(prefs::kNTPCustomLogoStart, 0); - prefs_->RegisterDoublePref(prefs::kNTPCustomLogoEnd, 0); - prefs_->RegisterDoublePref(prefs::kNTPPromoStart, 0); - prefs_->RegisterDoublePref(prefs::kNTPPromoEnd, 0); - prefs_->RegisterStringPref(prefs::kNTPPromoLine, std::string()); - prefs_->RegisterBooleanPref(prefs::kNTPPromoClosed, false); - prefs_->RegisterIntegerPref(prefs::kNTPPromoGroup, -1); - prefs_->RegisterIntegerPref(prefs::kNTPPromoBuild, - DEV_BUILD | BETA_BUILD | STABLE_BUILD); - prefs_->RegisterIntegerPref(prefs::kNTPPromoGroupTimeSlice, 0); - - // If the promo start is in the future, set a notification task to invalidate - // the NTP cache at the time of the promo start. - double promo_start = prefs_->GetDouble(prefs::kNTPPromoStart); - double promo_end = prefs_->GetDouble(prefs::kNTPPromoEnd); - ScheduleNotification(promo_start, promo_end); +void WebResourceService::PostNotification(int64 delay_ms) { + if (web_resource_update_scheduled_) + return; + if (delay_ms > 0) { + web_resource_update_scheduled_ = true; + MessageLoop::current()->PostDelayedTask(FROM_HERE, + service_factory_.NewRunnableMethod( + &WebResourceService::WebResourceStateChange), delay_ms); + } else if (delay_ms == 0) { + WebResourceStateChange(); + } } void WebResourceService::EndFetch() { @@ -270,56 +241,25 @@ void WebResourceService::EndFetch() { void WebResourceService::OnWebResourceUnpacked( const DictionaryValue& parsed_json) { - UnpackLogoSignal(parsed_json); - UnpackPromoSignal(parsed_json); + Unpack(parsed_json); EndFetch(); } void WebResourceService::WebResourceStateChange() { web_resource_update_scheduled_ = false; NotificationService* service = NotificationService::current(); - service->Notify(NotificationType::WEB_RESOURCE_STATE_CHANGED, + service->Notify(notification_type_, Source<WebResourceService>(this), NotificationService::NoDetails()); } -void WebResourceService::ScheduleNotification(double promo_start, - double promo_end) { - if (promo_start > 0 && promo_end > 0 && !web_resource_update_scheduled_) { - int64 ms_until_start = - static_cast<int64>((base::Time::FromDoubleT( - promo_start) - base::Time::Now()).InMilliseconds()); - int64 ms_until_end = - static_cast<int64>((base::Time::FromDoubleT( - promo_end) - base::Time::Now()).InMilliseconds()); - if (ms_until_start > 0) { - web_resource_update_scheduled_ = true; - MessageLoop::current()->PostDelayedTask(FROM_HERE, - service_factory_.NewRunnableMethod( - &WebResourceService::WebResourceStateChange), - ms_until_start); - } - if (ms_until_end > 0) { - web_resource_update_scheduled_ = true; - MessageLoop::current()->PostDelayedTask(FROM_HERE, - service_factory_.NewRunnableMethod( - &WebResourceService::WebResourceStateChange), - ms_until_end); - if (ms_until_start <= 0) { - // Notify immediately if time is between start and end. - WebResourceStateChange(); - } - } - } -} - void WebResourceService::StartAfterDelay() { - int64 delay = kStartResourceFetchDelay; + int64 delay = start_fetch_delay_; // Check whether we have ever put a value in the web resource cache; // if so, pull it out and see if it's time to update again. - if (prefs_->HasPrefPath(prefs::kNTPWebResourceCacheUpdate)) { + if (prefs_->HasPrefPath(last_update_time_pref_name_)) { std::string last_update_pref = - prefs_->GetString(prefs::kNTPWebResourceCacheUpdate); + prefs_->GetString(last_update_time_pref_name_); if (!last_update_pref.empty()) { double last_update_value; base::StringToDouble(last_update_pref, &last_update_value); @@ -327,8 +267,8 @@ void WebResourceService::StartAfterDelay() { static_cast<int64>((base::Time::Now() - base::Time::FromDoubleT( last_update_value)).InMilliseconds()); delay = ms_until_update > cache_update_delay_ ? - cache_update_delay_ : (ms_until_update < kStartResourceFetchDelay ? - kStartResourceFetchDelay : ms_until_update); + cache_update_delay_ : (ms_until_update < start_fetch_delay_ ? + start_fetch_delay_ : ms_until_update); } } // Start fetch and wait for UpdateResourceCache. @@ -340,250 +280,6 @@ void WebResourceService::UpdateResourceCache(const std::string& json_data) { client->Start(); // Set cache update time in preferences. - prefs_->SetString(prefs::kNTPWebResourceCacheUpdate, + prefs_->SetString(last_update_time_pref_name_, base::DoubleToString(base::Time::Now().ToDoubleT())); } - -void WebResourceService::UnpackTips(const DictionaryValue& parsed_json) { - // Get dictionary of cached preferences. - web_resource_cache_ = - prefs_->GetMutableDictionary(prefs::kNTPWebResourceCache); - - // The list of individual tips. - ListValue* tip_holder = new ListValue(); - web_resource_cache_->Set(WebResourceService::kTipCachePrefName, tip_holder); - - DictionaryValue* topic_dict; - ListValue* answer_list; - std::string topic_id; - std::string answer_id; - std::string inproduct; - int tip_counter = 0; - - if (parsed_json.GetDictionary("topic", &topic_dict)) { - if (topic_dict->GetString("topic_id", &topic_id)) - web_resource_cache_->SetString("topic_id", topic_id); - if (topic_dict->GetList("answers", &answer_list)) { - for (ListValue::const_iterator tip_iter = answer_list->begin(); - tip_iter != answer_list->end(); ++tip_iter) { - if (!(*tip_iter)->IsType(Value::TYPE_DICTIONARY)) - continue; - DictionaryValue* a_dic = - static_cast<DictionaryValue*>(*tip_iter); - if (a_dic->GetString("inproduct", &inproduct)) { - tip_holder->Append(Value::CreateStringValue(inproduct)); - } - tip_counter++; - } - // If tips exist, set current index to 0. - if (!inproduct.empty()) { - web_resource_cache_->SetInteger( - WebResourceService::kCurrentTipPrefName, 0); - } - } - } -} - -void WebResourceService::UnpackPromoSignal(const DictionaryValue& parsed_json) { - DictionaryValue* topic_dict; - ListValue* answer_list; - double old_promo_start = 0; - double old_promo_end = 0; - double promo_start = 0; - double promo_end = 0; - - // Check for preexisting start and end values. - if (prefs_->HasPrefPath(prefs::kNTPPromoStart) && - prefs_->HasPrefPath(prefs::kNTPPromoEnd)) { - old_promo_start = prefs_->GetDouble(prefs::kNTPPromoStart); - old_promo_end = prefs_->GetDouble(prefs::kNTPPromoEnd); - } - - // Check for newly received start and end values. - if (parsed_json.GetDictionary("topic", &topic_dict)) { - if (topic_dict->GetList("answers", &answer_list)) { - std::string promo_start_string = ""; - std::string promo_end_string = ""; - std::string promo_string = ""; - std::string promo_build = ""; - int promo_build_type = 0; - int time_slice_hrs = 0; - for (ListValue::const_iterator tip_iter = answer_list->begin(); - tip_iter != answer_list->end(); ++tip_iter) { - if (!(*tip_iter)->IsType(Value::TYPE_DICTIONARY)) - continue; - DictionaryValue* a_dic = - static_cast<DictionaryValue*>(*tip_iter); - std::string promo_signal; - if (a_dic->GetString("name", &promo_signal)) { - if (promo_signal == "promo_start") { - a_dic->GetString("question", &promo_build); - size_t split = promo_build.find(":"); - if (split != std::string::npos && - base::StringToInt(promo_build.substr(0, split), - &promo_build_type) && - base::StringToInt(promo_build.substr(split+1), - &time_slice_hrs) && - promo_build_type >= 0 && - promo_build_type <= (DEV_BUILD | BETA_BUILD | STABLE_BUILD) && - time_slice_hrs >= 0 && - time_slice_hrs <= kMaxTimeSliceHours) { - prefs_->SetInteger(prefs::kNTPPromoBuild, promo_build_type); - prefs_->SetInteger(prefs::kNTPPromoGroupTimeSlice, - time_slice_hrs); - } else { - // If no time data or bad time data are set, show promo on all - // builds with no time slicing. - prefs_->SetInteger(prefs::kNTPPromoBuild, - DEV_BUILD | BETA_BUILD | STABLE_BUILD); - prefs_->SetInteger(prefs::kNTPPromoGroupTimeSlice, 0); - } - a_dic->GetString("inproduct", &promo_start_string); - a_dic->GetString("tooltip", &promo_string); - prefs_->SetString(prefs::kNTPPromoLine, promo_string); - srand(static_cast<uint32>(time(NULL))); - prefs_->SetInteger(prefs::kNTPPromoGroup, - rand() % kNTPPromoGroupSize); - } else if (promo_signal == "promo_end") { - a_dic->GetString("inproduct", &promo_end_string); - } - } - } - if (!promo_start_string.empty() && - promo_start_string.length() > 0 && - !promo_end_string.empty() && - promo_end_string.length() > 0) { - base::Time start_time; - base::Time end_time; - if (base::Time::FromString( - ASCIIToWide(promo_start_string).c_str(), &start_time) && - base::Time::FromString( - ASCIIToWide(promo_end_string).c_str(), &end_time)) { - // Add group time slice, adjusted from hours to seconds. - promo_start = start_time.ToDoubleT() + - (prefs_->FindPreference(prefs::kNTPPromoGroup) ? - prefs_->GetInteger(prefs::kNTPPromoGroup) * - time_slice_hrs * 60 * 60 : 0); - promo_end = end_time.ToDoubleT(); - } - } - } - } - - // If start or end times have changed, trigger a new web resource - // notification, so that the logo on the NTP is updated. This check is - // outside the reading of the web resource data, because the absence of - // dates counts as a triggering change if there were dates before. - // Also reset the promo closed preference, to signal a new promo. - if (!(old_promo_start == promo_start) || - !(old_promo_end == promo_end)) { - prefs_->SetDouble(prefs::kNTPPromoStart, promo_start); - prefs_->SetDouble(prefs::kNTPPromoEnd, promo_end); - prefs_->SetBoolean(prefs::kNTPPromoClosed, false); - ScheduleNotification(promo_start, promo_end); - } -} - -void WebResourceService::UnpackLogoSignal(const DictionaryValue& parsed_json) { - DictionaryValue* topic_dict; - ListValue* answer_list; - double old_logo_start = 0; - double old_logo_end = 0; - double logo_start = 0; - double logo_end = 0; - - // Check for preexisting start and end values. - if (prefs_->HasPrefPath(prefs::kNTPCustomLogoStart) && - prefs_->HasPrefPath(prefs::kNTPCustomLogoEnd)) { - old_logo_start = prefs_->GetDouble(prefs::kNTPCustomLogoStart); - old_logo_end = prefs_->GetDouble(prefs::kNTPCustomLogoEnd); - } - - // Check for newly received start and end values. - if (parsed_json.GetDictionary("topic", &topic_dict)) { - if (topic_dict->GetList("answers", &answer_list)) { - std::string logo_start_string = ""; - std::string logo_end_string = ""; - for (ListValue::const_iterator tip_iter = answer_list->begin(); - tip_iter != answer_list->end(); ++tip_iter) { - if (!(*tip_iter)->IsType(Value::TYPE_DICTIONARY)) - continue; - DictionaryValue* a_dic = - static_cast<DictionaryValue*>(*tip_iter); - std::string logo_signal; - if (a_dic->GetString("name", &logo_signal)) { - if (logo_signal == "custom_logo_start") { - a_dic->GetString("inproduct", &logo_start_string); - } else if (logo_signal == "custom_logo_end") { - a_dic->GetString("inproduct", &logo_end_string); - } - } - } - if (!logo_start_string.empty() && - logo_start_string.length() > 0 && - !logo_end_string.empty() && - logo_end_string.length() > 0) { - base::Time start_time; - base::Time end_time; - if (base::Time::FromString( - ASCIIToWide(logo_start_string).c_str(), &start_time) && - base::Time::FromString( - ASCIIToWide(logo_end_string).c_str(), &end_time)) { - logo_start = start_time.ToDoubleT(); - logo_end = end_time.ToDoubleT(); - } - } - } - } - - // If logo start or end times have changed, trigger a new web resource - // notification, so that the logo on the NTP is updated. This check is - // outside the reading of the web resource data, because the absence of - // dates counts as a triggering change if there were dates before. - if (!(old_logo_start == logo_start) || - !(old_logo_end == logo_end)) { - prefs_->SetDouble(prefs::kNTPCustomLogoStart, logo_start); - prefs_->SetDouble(prefs::kNTPCustomLogoEnd, logo_end); - NotificationService* service = NotificationService::current(); - service->Notify(NotificationType::WEB_RESOURCE_STATE_CHANGED, - Source<WebResourceService>(this), - NotificationService::NoDetails()); - } -} - -namespace WebResourceServiceUtil { - -bool CanShowPromo(Profile* profile) { - bool promo_closed = false; - PrefService* prefs = profile->GetPrefs(); - if (prefs->HasPrefPath(prefs::kNTPPromoClosed)) - promo_closed = prefs->GetBoolean(prefs::kNTPPromoClosed); - - // Only show if not synced. - bool is_synced = - (profile->HasProfileSyncService() && - sync_ui_util::GetStatus( - profile->GetProfileSyncService()) == sync_ui_util::SYNCED); - - // GetVersionStringModifier hits the registry. See http://crbug.com/70898. - base::ThreadRestrictions::ScopedAllowIO allow_io; - const std::string channel = platform_util::GetVersionStringModifier(); - bool is_promo_build = false; - if (prefs->HasPrefPath(prefs::kNTPPromoBuild)) { - int builds_allowed = prefs->GetInteger(prefs::kNTPPromoBuild); - if (channel == "dev") { - is_promo_build = (DEV_BUILD & builds_allowed) != 0; - } else if (channel == "beta") { - is_promo_build = (BETA_BUILD & builds_allowed) != 0; - } else if (channel == "stable") { - is_promo_build = (STABLE_BUILD & builds_allowed) != 0; - } else { - is_promo_build = true; - } - } - - return !promo_closed && !is_synced && is_promo_build; -} - -} // namespace WebResourceService - diff --git a/chrome/browser/web_resource/web_resource_service.h b/chrome/browser/web_resource/web_resource_service.h index 815eaf7..1b4b680 100644 --- a/chrome/browser/web_resource/web_resource_service.h +++ b/chrome/browser/web_resource/web_resource_service.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -8,33 +8,24 @@ #include <string> -#include "base/file_path.h" -#include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/utility_process_host.h" -#include "chrome/common/web_resource/web_resource_unpacker.h" +#include "chrome/common/notification_type.h" +class PrefService; class Profile; -namespace WebResourceServiceUtil { - -// Certain promotions should only be shown to certain classes of users. This -// function will change to reflect each kind of promotion. -bool CanShowPromo(Profile* profile); - -} // namespace WebResourceService - -// A WebResourceService fetches data from a web resource server to be used to -// dynamically change the appearance of the New Tab Page. For example, it has -// been used to fetch "tips" to be displayed on the NTP, or to display -// promotional messages to certain groups of Chrome users. -// -// TODO(mirandac): Arrange for a server to be set up specifically for promo -// messages, which have until now been piggybacked onto the old tips server -// structure. (see http://crbug.com/70634 for details.) +// A WebResourceService fetches data from a web resource server and store +// locally as user preference. class WebResourceService : public UtilityProcessHost::Client { public: - explicit WebResourceService(Profile* profile); + WebResourceService(Profile* profile, + const char* web_resource_server, + bool apply_locale_to_url_, + NotificationType::Type notification_type, + const char* last_update_time_pref_name, + int start_fetch_delay, + int cache_update_delay); // Sleep until cache needs to be updated, but always for at least 5 seconds // so we don't interfere with startup. Then begin updating resources. @@ -44,107 +35,19 @@ class WebResourceService // the process that will parse the JSON, and then update the cache. void UpdateResourceCache(const std::string& json_data); - // Unpack the web resource as a set of tips. Expects json in the form of: - // { - // "lang": "en", - // "topic": { - // "topid_id": "24013", - // "topics": [ - // ], - // "answers": [ - // { - // "answer_id": "18625", - // "inproduct": "Text here will be shown as a tip", - // }, - // ... - // ] - // } - // } - // - // Public for unit testing. - void UnpackTips(const DictionaryValue& parsed_json); - - // Unpack the web resource as a custom promo signal. Expects a start and end - // signal, with the promo to be shown in the tooltip of the start signal - // field. Delivery will be in json in the form of: - // { - // "topic": { - // "answers": [ - // { - // "answer_id": "1067976", - // "name": "promo_start", - // "question": "1:24", - // "tooltip": - // "Click \u003ca href=http://www.google.com\u003ehere\u003c/a\u003e!", - // "inproduct": "10/8/09 12:00", - // "inproduct_target": null - // }, - // { - // "answer_id": "1067976", - // "name": "promo_end", - // "question": "", - // "tooltip": "", - // "inproduct": "10/8/11 12:00", - // "inproduct_target": null - // }, - // ... - // ] - // } - // } - // - // Because the promo signal data is piggybacked onto the tip server, the - // values don't exactly correspond with the field names: - // - // For "promo_start" or "promo_end", the date to start or stop showing the - // promotional line is given by the "inproduct" line. - // For "promo_start", the promotional line itself is given in the "tooltip" - // field. The "question" field gives the type of builds that should be shown - // this promo (see the BuildType enum in web_resource_service.cc) and the - // number of hours that each promo group should see it, separated by ":". - // For example, "7:24" would indicate that all builds should see the promo, - // and each group should see it for 24 hours. - // - // Public for unit testing. - void UnpackPromoSignal(const DictionaryValue& parsed_json); - - // Unpack the web resource as a custom logo signal. Expects a start and end - // signal. Delivery will be in json in the form of: - // { - // "topic": { - // "answers": [ - // { - // "answer_id": "107366", - // "name": "custom_logo_start", - // "question": "", - // "tooltip": "", - // "inproduct": "10/8/09 12:00", - // "inproduct_target": null - // }, - // { - // "answer_id": "107366", - // "name": "custom_logo_end", - // "question": "", - // "tooltip": "", - // "inproduct": "10/8/09 12:00", - // "inproduct_target": null - // }, - // ... - // ] - // } - // } - // - // Public for unit testing. - void UnpackLogoSignal(const DictionaryValue& parsed_json); - - int cache_update_delay() const { return cache_update_delay_; } - - Profile* profile() const { return profile_; } - - static const char* kCurrentTipPrefName; - static const char* kTipCachePrefName; - - // Default server of dynamically loaded NTP HTML elements (promotions, tips): - static const char* kDefaultWebResourceServer; + protected: + virtual ~WebResourceService(); + + virtual void Unpack(const DictionaryValue& parsed_json) = 0; + + // If delay_ms is positive, schedule notification with the delay. + // If delay_ms is 0, notify immediately by calling WebResourceStateChange(). + // If delay_ms is negative, do nothing. + void PostNotification(int64 delay_ms); + + // We need to be able to load parsed resource data into preferences file, + // and get proper install directory. + PrefService* prefs_; private: class WebResourceFetcher; @@ -152,10 +55,6 @@ class WebResourceService class UnpackerClient; - ~WebResourceService(); - - void Init(); - // Set in_fetch_ to false, clean up temp directories (in the future). void EndFetch(); @@ -165,16 +64,6 @@ class WebResourceService // Notify listeners that the state of a web resource has changed. void WebResourceStateChange(); - // Schedule a notification that a web resource is either going to become - // available or be no longer valid. - void ScheduleNotification(double ms_start_time, double ms_end_time); - - // We need to be able to load parsed resource data into preferences file, - // and get proper install directory. - PrefService* prefs_; - - // Display and fetch of promo lines depends on data associated with a user's - // profile. Profile* profile_; scoped_ptr<WebResourceFetcher> web_resource_fetcher_; @@ -186,15 +75,26 @@ class WebResourceService // Page immediately when a new web resource should be shown or removed. ScopedRunnableMethodFactory<WebResourceService> service_factory_; - // Gets mutable dictionary attached to user's preferences, so that we - // can write resource data back to user's pref file. - DictionaryValue* web_resource_cache_; - // True if we are currently mid-fetch. If we are asked to start a fetch // when we are still fetching resource data, schedule another one in // kCacheUpdateDelay time, and silently exit. bool in_fetch_; + // URL that hosts the web resource. + const char* web_resource_server_; + + // Indicates whether we should append locale to the web resource server URL. + bool apply_locale_to_url_; + + // Notification type when an update is done. + NotificationType::Type notification_type_; + + // Pref name to store the last update's time. + const char* last_update_time_pref_name_; + + // Delay on first fetch so we don't interfere with startup. + int start_fetch_delay_; + // Delay between calls to update the web resource cache. This delay may be // different for different builds of Chrome. int cache_update_delay_; |