diff options
author | ibraaaa@google.com <ibraaaa@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-02 20:41:14 +0000 |
---|---|---|
committer | ibraaaa@google.com <ibraaaa@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-02 20:41:14 +0000 |
commit | 2366a3a7e0a7b9a398ae747963ab7fcb4043a375 (patch) | |
tree | 8edec5720714fe015b097d27054081de1b58004b | |
parent | 03c956ae04e3802df6afc9ac5fe1dad8737da2db (diff) | |
download | chromium_src-2366a3a7e0a7b9a398ae747963ab7fcb4043a375.zip chromium_src-2366a3a7e0a7b9a398ae747963ab7fcb4043a375.tar.gz chromium_src-2366a3a7e0a7b9a398ae747963ab7fcb4043a375.tar.bz2 |
Plugins resource service.
This CL adds a periodic request of plugin metadata files from a URL. The fetched files are used to update the current metadata.
BUG=124396
Review URL: https://chromiumcodereview.appspot.com/10990059
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@159755 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/browser_process_impl.cc | 11 | ||||
-rw-r--r-- | chrome/browser/browser_process_impl.h | 7 | ||||
-rw-r--r-- | chrome/browser/plugins/plugin_finder.cc | 168 | ||||
-rw-r--r-- | chrome/browser/plugins/plugin_finder.h | 13 | ||||
-rw-r--r-- | chrome/browser/prefs/browser_prefs.cc | 8 | ||||
-rw-r--r-- | chrome/browser/web_resource/plugins_resource_service.cc | 76 | ||||
-rw-r--r-- | chrome/browser/web_resource/plugins_resource_service.h | 27 | ||||
-rw-r--r-- | chrome/browser/web_resource/web_resource_service.h | 1 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 4 | ||||
-rw-r--r-- | chrome/common/chrome_switches.cc | 5 | ||||
-rw-r--r-- | chrome/common/chrome_switches.h | 4 | ||||
-rw-r--r-- | chrome/common/pref_names.cc | 8 | ||||
-rw-r--r-- | chrome/common/pref_names.h | 4 |
13 files changed, 251 insertions, 85 deletions
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index 8782d81..39f84ea 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc @@ -100,6 +100,10 @@ #include "chrome/browser/chromeos/oom_priority_manager.h" #endif // defined(OS_CHROMEOS) +#if defined(ENABLE_PLUGIN_INSTALLATION) +#include "chrome/browser/web_resource/plugins_resource_service.h" +#endif + #if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) // How often to check if the persistent instance of Chrome needs to restart // to install an update. @@ -795,6 +799,13 @@ void BrowserProcessImpl::PreMainMessageLoopRun() { // Triggers initialization of the singleton instance on UI thread. PluginFinder::GetInstance()->Init(); + +#if defined(ENABLE_PLUGIN_INSTALLATION) + if (!plugins_resource_service_) { + plugins_resource_service_ = new PluginsResourceService(local_state()); + plugins_resource_service_->StartAfterDelay(); + } +#endif } void BrowserProcessImpl::CreateIconManager() { diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h index 404db25..485d184 100644 --- a/chrome/browser/browser_process_impl.h +++ b/chrome/browser/browser_process_impl.h @@ -28,6 +28,10 @@ class ChromeResourceDispatcherHostDelegate; class CommandLine; class RemoteDebuggingServer; +#if defined(ENABLE_PLUGIN_INSTALLATION) +class PluginsResourceService; +#endif + namespace policy { class BrowserPolicyConnector; class PolicyService; @@ -253,6 +257,9 @@ class BrowserProcessImpl : public BrowserProcess, scoped_refptr<CRLSetFetcher> crl_set_fetcher_; #endif +#if defined(ENABLE_PLUGIN_INSTALLATION) + scoped_refptr<PluginsResourceService> plugins_resource_service_; +#endif // TODO(eroman): Remove this when done debugging 113031. This tracks // the callstack which released the final module reference count. base::debug::StackTrace release_last_reference_callstack_; diff --git a/chrome/browser/plugins/plugin_finder.cc b/chrome/browser/plugins/plugin_finder.cc index aded8b6..91345d2 100644 --- a/chrome/browser/plugins/plugin_finder.cc +++ b/chrome/browser/plugins/plugin_finder.cc @@ -54,6 +54,54 @@ static string16 GetGroupName(const webkit::WebPluginInfo& plugin) { #endif } +PluginMetadata* CreatePluginMetadata( + const std::string& identifier, + const DictionaryValue* plugin_dict) { + std::string url; + bool success = plugin_dict->GetString("url", &url); + std::string help_url; + plugin_dict->GetString("help_url", &help_url); + string16 name; + success = plugin_dict->GetString("name", &name); + DCHECK(success); + bool display_url = false; + plugin_dict->GetBoolean("displayurl", &display_url); + string16 group_name_matcher; + success = plugin_dict->GetString("group_name_matcher", &group_name_matcher); + DCHECK(success); + + PluginMetadata* plugin = new PluginMetadata(identifier, + name, + display_url, + GURL(url), + GURL(help_url), + group_name_matcher); + const ListValue* versions = NULL; + if (plugin_dict->GetList("versions", &versions)) { + for (ListValue::const_iterator it = versions->begin(); + it != versions->end(); ++it) { + DictionaryValue* version_dict = NULL; + if (!(*it)->GetAsDictionary(&version_dict)) { + NOTREACHED(); + continue; + } + std::string version; + success = version_dict->GetString("version", &version); + DCHECK(success); + std::string status_str; + success = version_dict->GetString("status", &status_str); + DCHECK(success); + PluginMetadata::SecurityStatus status = + PluginMetadata::SECURITY_STATUS_UP_TO_DATE; + success = PluginMetadata::ParseSecurityStatus(status_str, &status); + DCHECK(success); + plugin->AddVersion(Version(version), status); + } + } + + return plugin; +} + } // namespace // static @@ -67,27 +115,18 @@ PluginFinder::PluginFinder() { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); } -// TODO(ibraaaa): initialize |plugin_list_| from Local State. -// http://crbug.com/124396 void PluginFinder::Init() { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - plugin_list_.reset(LoadPluginList()); +#if defined(ENABLE_PLUGIN_INSTALLATION) + const base::DictionaryValue* metadata = + g_browser_process->local_state()->GetDictionary(prefs::kPluginsMetadata); + plugin_list_.reset( + metadata->empty() ? LoadPluginList() : metadata->DeepCopy()); +#endif if (!plugin_list_.get()) plugin_list_.reset(new DictionaryValue()); - for (DictionaryValue::Iterator plugin_it(*plugin_list_); - plugin_it.HasNext(); plugin_it.Advance()) { - DictionaryValue* plugin = NULL; - const std::string& identifier = plugin_it.key(); - if (plugin_list_->GetDictionaryWithoutPathExpansion(identifier, &plugin)) { - PluginMetadata* metadata = CreatePluginMetadata(identifier, plugin); - identifier_plugin_[identifier] = metadata; - -#if defined(ENABLE_PLUGIN_INSTALLATION) - installers_[identifier] = new PluginInstaller(); -#endif - } - } + InitInternal(); } // static @@ -127,6 +166,7 @@ bool PluginFinder::FindPlugin( const std::string& language, PluginInstaller** installer, scoped_ptr<PluginMetadata>* plugin_metadata) { + base::AutoLock lock(mutex_); if (g_browser_process->local_state()->GetBoolean(prefs::kDisablePluginFinder)) return false; for (DictionaryValue::Iterator plugin_it(*plugin_list_); @@ -141,17 +181,14 @@ bool PluginFinder::FindPlugin( if (language_str != language) continue; const ListValue* mime_types = NULL; - plugin->GetList("mime_types", &mime_types); - DCHECK(success); - for (ListValue::const_iterator mime_type_it = mime_types->begin(); - mime_type_it != mime_types->end(); ++mime_type_it) { - std::string mime_type_str; - success = (*mime_type_it)->GetAsString(&mime_type_str); - DCHECK(success); - if (mime_type_str == mime_type) { - std::string identifier = plugin_it.key(); - { - base::AutoLock lock(mutex_); + if (plugin->GetList("mime_types", &mime_types)) { + for (ListValue::const_iterator mime_type_it = mime_types->begin(); + mime_type_it != mime_types->end(); ++mime_type_it) { + std::string mime_type_str; + success = (*mime_type_it)->GetAsString(&mime_type_str); + DCHECK(success); + if (mime_type_str == mime_type) { + std::string identifier = plugin_it.key(); std::map<std::string, PluginMetadata*>::const_iterator metadata_it = identifier_plugin_.find(identifier); DCHECK(metadata_it != identifier_plugin_.end()); @@ -187,6 +224,17 @@ bool PluginFinder::FindPluginWithIdentifier( return false; } + +void PluginFinder::ReinitializePlugins( + const base::DictionaryValue& json_metadata) { + base::AutoLock lock(mutex_); + STLDeleteValues(&identifier_plugin_); + identifier_plugin_.clear(); + name_plugin_.clear(); + + plugin_list_.reset(json_metadata.DeepCopy()); + InitInternal(); +} #endif string16 PluginFinder::FindPluginNameWithIdentifier( @@ -201,55 +249,6 @@ string16 PluginFinder::FindPluginNameWithIdentifier( return name.empty() ? UTF8ToUTF16(identifier) : name; } -PluginMetadata* PluginFinder::CreatePluginMetadata( - const std::string& identifier, - const DictionaryValue* plugin_dict) { - DCHECK(!identifier_plugin_[identifier]); - std::string url; - bool success = plugin_dict->GetString("url", &url); - std::string help_url; - plugin_dict->GetString("help_url", &help_url); - string16 name; - success = plugin_dict->GetString("name", &name); - DCHECK(success); - bool display_url = false; - plugin_dict->GetBoolean("displayurl", &display_url); - string16 group_name_matcher; - success = plugin_dict->GetString("group_name_matcher", &group_name_matcher); - DCHECK(success); - - PluginMetadata* plugin = new PluginMetadata(identifier, - name, - display_url, - GURL(url), - GURL(help_url), - group_name_matcher); - const ListValue* versions = NULL; - if (plugin_dict->GetList("versions", &versions)) { - for (ListValue::const_iterator it = versions->begin(); - it != versions->end(); ++it) { - DictionaryValue* version_dict = NULL; - if (!(*it)->GetAsDictionary(&version_dict)) { - NOTREACHED(); - continue; - } - std::string version; - success = version_dict->GetString("version", &version); - DCHECK(success); - std::string status_str; - success = version_dict->GetString("status", &status_str); - DCHECK(success); - PluginMetadata::SecurityStatus status = - PluginMetadata::SECURITY_STATUS_UP_TO_DATE; - success = PluginMetadata::ParseSecurityStatus(status_str, &status); - DCHECK(success); - plugin->AddVersion(Version(version), status); - } - } - - return plugin; -} - scoped_ptr<PluginMetadata> PluginFinder::GetPluginMetadata( const webkit::WebPluginInfo& plugin) { base::AutoLock lock(mutex_); @@ -278,3 +277,20 @@ scoped_ptr<PluginMetadata> PluginFinder::GetPluginMetadata( identifier_plugin_[identifier] = metadata; return metadata->Clone(); } + +void PluginFinder::InitInternal() { + for (DictionaryValue::Iterator plugin_it(*plugin_list_); + plugin_it.HasNext(); plugin_it.Advance()) { + DictionaryValue* plugin = NULL; + const std::string& identifier = plugin_it.key(); + if (plugin_list_->GetDictionaryWithoutPathExpansion(identifier, &plugin)) { + DCHECK(!identifier_plugin_[identifier]); + identifier_plugin_[identifier] = CreatePluginMetadata(identifier, plugin); + +#if defined(ENABLE_PLUGIN_INSTALLATION) + if (installers_.find(identifier) == installers_.end()) + installers_[identifier] = new PluginInstaller(); +#endif + } + } +} diff --git a/chrome/browser/plugins/plugin_finder.h b/chrome/browser/plugins/plugin_finder.h index dacecb4..ef08867 100644 --- a/chrome/browser/plugins/plugin_finder.h +++ b/chrome/browser/plugins/plugin_finder.h @@ -38,6 +38,8 @@ class PluginFinder { void Init(); #if defined(ENABLE_PLUGIN_INSTALLATION) + void ReinitializePlugins(const base::DictionaryValue& json_metadata); + // Finds a plug-in for the given MIME type and language (specified as an IETF // language tag, i.e. en-US). If found, sets |installer| to the // corresponding PluginInstaller and |plugin_metadata| to a copy of the @@ -75,12 +77,8 @@ class PluginFinder { // Returns NULL if the plug-in list couldn't be parsed. static base::DictionaryValue* LoadPluginList(); - PluginMetadata* CreatePluginMetadata( - const std::string& identifier, - const base::DictionaryValue* plugin_dict); + void InitInternal(); - // Initialized in |Init()| method and is read-only after that. - // No need to be synchronized. scoped_ptr<base::DictionaryValue> plugin_list_; #if defined(ENABLE_PLUGIN_INSTALLATION) std::map<std::string, PluginInstaller*> installers_; @@ -93,9 +91,8 @@ class PluginFinder { // in |identifier_plugin_| (Double De-allocation). std::map<string16, PluginMetadata*> name_plugin_; - // Synchronization for |installers_|, |identifier_plugin_| and - // |name_plugin_| are required since multiple threads - // can be accessing them concurrently. + // Synchronization for the above member variables is + // required since multiple threads can be accessing them concurrently. base::Lock mutex_; DISALLOW_COPY_AND_ASSIGN(PluginFinder); diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 47e1a5b..47f54a8 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc @@ -120,6 +120,10 @@ #include "chrome/browser/ui/webui/ntp/android/promo_handler.h" #endif +#if defined(ENABLE_PLUGIN_INSTALLATION) +#include "chrome/browser/web_resource/plugins_resource_service.h" +#endif + namespace { enum MigratedPreferences { @@ -153,6 +157,10 @@ void RegisterLocalState(PrefService* local_state) { WebCacheManager::RegisterPrefs(local_state); chrome::RegisterScreenshotPrefs(local_state); +#if defined(ENABLE_PLUGIN_INSTALLATION) + PluginsResourceService::RegisterPrefs(local_state); +#endif + #if defined(ENABLE_CONFIGURATION_POLICY) policy::CloudPolicySubsystem::RegisterPrefs(local_state); policy::PolicyStatisticsCollector::RegisterPrefs(local_state); diff --git a/chrome/browser/web_resource/plugins_resource_service.cc b/chrome/browser/web_resource/plugins_resource_service.cc new file mode 100644 index 0000000..13c45c0 --- /dev/null +++ b/chrome/browser/web_resource/plugins_resource_service.cc @@ -0,0 +1,76 @@ +// Copyright (c) 2012 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/plugins_resource_service.h" + +#include "base/command_line.h" +#include "chrome/browser/plugins/plugin_finder.h" +#include "chrome/browser/prefs/pref_service.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/pref_names.h" +#include "googleurl/src/gurl.h" + +namespace { + +// Delay on first fetch so we don't interfere with startup. +const int kStartResourceFetchDelayMs = 60 * 1000; + +// Delay between calls to update the cache 1 day and 2 minutes in testing mode. +const int kCacheUpdateDelayMs = 24 * 60 * 60 * 1000; +const int kTestCacheUpdateDelayMs = 2 * 60 * 1000; + +const char kPluginsServerUrl[] = "https://www.gstatic.com/chrome/config/"; + +bool IsTest() { + return CommandLine::ForCurrentProcess()->HasSwitch( + switches::kPluginsMetadataServerURL); +} + +GURL GetPluginsServerURL() { + std::string filename; +#if defined(OS_WIN) + filename = "plugins_win.json"; +#elif defined(OS_LINUX) + filename = "plugins_linux.json"; +#elif defined(OS_MACOSX) + filename = "plugins_mac.json"; +#else + NOTREACHED(); +#endif + + std::string test_url = + CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + switches::kPluginsMetadataServerURL); + return GURL(IsTest() ? test_url : kPluginsServerUrl + filename); +} + +int GetCacheUpdateDelay() { + return IsTest() ? kTestCacheUpdateDelayMs : kCacheUpdateDelayMs; +} + +} // namespace + +PluginsResourceService::PluginsResourceService(PrefService* local_state) + : WebResourceService(local_state, + GetPluginsServerURL(), + false, + prefs::kPluginsResourceCacheUpdate, + kStartResourceFetchDelayMs, + GetCacheUpdateDelay()) { +} + +PluginsResourceService::~PluginsResourceService() { +} + +// static +void PluginsResourceService::RegisterPrefs(PrefService* local_state) { + local_state->RegisterDictionaryPref( + prefs::kPluginsMetadata, new base::DictionaryValue()); + local_state->RegisterStringPref(prefs::kPluginsResourceCacheUpdate, "0"); +} + +void PluginsResourceService::Unpack(const DictionaryValue& parsed_json) { + prefs_->Set(prefs::kPluginsMetadata, parsed_json); + PluginFinder::GetInstance()->ReinitializePlugins(parsed_json); +} diff --git a/chrome/browser/web_resource/plugins_resource_service.h b/chrome/browser/web_resource/plugins_resource_service.h new file mode 100644 index 0000000..7114cc7 --- /dev/null +++ b/chrome/browser/web_resource/plugins_resource_service.h @@ -0,0 +1,27 @@ +// Copyright (c) 2012 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_PLUGINS_RESOURCE_SERVICE_H_ +#define CHROME_BROWSER_WEB_RESOURCE_PLUGINS_RESOURCE_SERVICE_H_ + +#include "chrome/browser/web_resource/web_resource_service.h" + +// This resource service periodically fetches plug-in metadata +// from a remote server and updates local state and PluginFinder. +class PluginsResourceService : public WebResourceService { + public: + explicit PluginsResourceService(PrefService* local_state); + + static void RegisterPrefs(PrefService* local_state); + + private: + virtual ~PluginsResourceService(); + + // WebResourceService override to process the parsed information. + virtual void Unpack(const base::DictionaryValue& parsed_json) OVERRIDE; + + DISALLOW_COPY_AND_ASSIGN(PluginsResourceService); +}; + +#endif // CHROME_BROWSER_WEB_RESOURCE_PLUGINS_RESOURCE_SERVICE_H_ diff --git a/chrome/browser/web_resource/web_resource_service.h b/chrome/browser/web_resource/web_resource_service.h index 57e61cd..8863312 100644 --- a/chrome/browser/web_resource/web_resource_service.h +++ b/chrome/browser/web_resource/web_resource_service.h @@ -15,7 +15,6 @@ #include "net/url_request/url_fetcher_delegate.h" class PrefService; -class ResourceDispatcherHost; namespace base { class DictionaryValue; diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index d6493b53..d06e088 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -2053,6 +2053,8 @@ 'browser/web_resource/json_asynchronous_unpacker.h', 'browser/web_resource/notification_promo.cc', 'browser/web_resource/notification_promo.h', + 'browser/web_resource/plugins_resource_service.cc', + 'browser/web_resource/plugins_resource_service.h', 'browser/web_resource/promo_resource_service.cc', 'browser/web_resource/promo_resource_service.h', 'browser/web_resource/web_resource_service.cc', @@ -2679,6 +2681,8 @@ 'browser/plugins/plugin_installer.h', 'browser/plugins/plugin_installer_observer.cc', 'browser/plugins/plugin_installer_observer.h', + 'browser/web_resource/plugins_resource_service.cc', + 'browser/web_resource/plugins_resource_service.h', ], }], ['enable_protector_service==0', { diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index b6af103..640d03c 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -1345,6 +1345,11 @@ const char kWindowSize[] = "window-size"; // use Chromium's network stack to fetch, and V8 to evaluate. const char kWinHttpProxyResolver[] = "winhttp-proxy-resolver"; +#if defined(ENABLE_PLUGIN_INSTALLATION) +// Specifies a custom URL for fetching plug-ins metadata. Used for testing. +const char kPluginsMetadataServerURL[] = "plugins-metadata-server-url"; +#endif + #if defined(OS_ANDROID) // Use the tablet specific UI components when available. const char kTabletUI[] = "tablet-ui"; diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index dab2ded..db65d40 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -359,6 +359,10 @@ extern const char kWindowPosition[]; extern const char kWindowSize[]; extern const char kWinHttpProxyResolver[]; +#if defined(ENABLE_PLUGIN_INSTALLATION) +extern const char kPluginsMetadataServerURL[]; +#endif + #if defined(OS_ANDROID) extern const char kTabletUI[]; #endif diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index f05535d..8d531c2 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc @@ -882,6 +882,14 @@ const char kPluginsAllowOutdated[] = "plugins.allow_outdated"; // be always allowed or not. const char kPluginsAlwaysAuthorize[] = "plugins.always_authorize"; +#if defined(ENABLE_PLUGIN_INSTALLATION) +// Dictionary holding plug-ins metadata. +const char kPluginsMetadata[] = "plugins.metadata"; + +// Last update time of plug-ins resource cache. +const char kPluginsResourceCacheUpdate[] = "plugins.resource_cache_update"; +#endif + // Boolean that indicates whether we should check if we are the default browser // on start-up. const char kCheckDefaultBrowser[] = "browser.check_default_browser"; diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 13d4dd7..0f1fe5c 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h @@ -319,6 +319,10 @@ extern const char kPluginsMigratedToPepperFlash[]; extern const char kPluginsShowDetails[]; extern const char kPluginsAllowOutdated[]; extern const char kPluginsAlwaysAuthorize[]; +#if defined(ENABLE_PLUGIN_INSTALLATION) +extern const char kPluginsMetadata[]; +extern const char kPluginsResourceCacheUpdate[]; +#endif extern const char kCheckDefaultBrowser[]; #if defined(OS_WIN) extern const char kSuppressSwitchToMetroModeOnSetDefault[]; |