| OLD | NEW | 
|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "chrome/browser/plugins/plugin_finder.h" | 5 #include "chrome/browser/plugins/plugin_finder.h" | 
| 6 | 6 | 
| 7 #include "base/bind.h" | 7 #include "base/bind.h" | 
| 8 #include "base/json/json_reader.h" | 8 #include "base/json/json_reader.h" | 
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" | 
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" | 
| 11 #include "base/sys_string_conversions.h" | 11 #include "base/sys_string_conversions.h" | 
| 12 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" | 
| 13 #include "base/values.h" | 13 #include "base/values.h" | 
| 14 #include "chrome/browser/browser_process.h" | 14 #include "chrome/browser/browser_process.h" | 
| 15 #include "chrome/browser/plugins/plugin_installer.h" | 15 #include "chrome/browser/plugins/plugin_installer.h" | 
| 16 #include "chrome/browser/prefs/pref_service.h" | 16 #include "chrome/browser/prefs/pref_service.h" | 
| 17 #include "chrome/common/pref_names.h" | 17 #include "chrome/common/pref_names.h" | 
| 18 #include "content/public/browser/browser_thread.h" | 18 #include "content/public/browser/browser_thread.h" | 
| 19 #include "content/public/browser/plugin_service.h" | 19 #include "content/public/browser/plugin_service.h" | 
| 20 #include "googleurl/src/gurl.h" | 20 #include "googleurl/src/gurl.h" | 
| 21 #include "grit/browser_resources.h" | 21 #include "grit/browser_resources.h" | 
| 22 #include "ui/base/layout.h" | 22 #include "ui/base/layout.h" | 
| 23 #include "ui/base/resource/resource_bundle.h" | 23 #include "ui/base/resource/resource_bundle.h" | 
| 24 | 24 | 
|  | 25 #if defined(ENABLE_PLUGIN_INSTALLATION) | 
|  | 26 #include "chrome/browser/plugins/plugin_installer.h" | 
|  | 27 #endif | 
|  | 28 | 
| 25 using base::DictionaryValue; | 29 using base::DictionaryValue; | 
| 26 using content::PluginService; | 30 using content::PluginService; | 
| 27 | 31 | 
| 28 namespace { | 32 namespace { | 
| 29 | 33 | 
| 30 // Gets the base name of the file path as the identifier. | 34 // Gets the base name of the file path as the identifier. | 
| 31 static std::string GetIdentifier(const webkit::WebPluginInfo& plugin) { | 35 static std::string GetIdentifier(const webkit::WebPluginInfo& plugin) { | 
| 32 #if defined(OS_POSIX) | 36 #if defined(OS_POSIX) | 
| 33   return plugin.path.BaseName().value(); | 37   return plugin.path.BaseName().value(); | 
| 34 #elif defined(OS_WIN) | 38 #elif defined(OS_WIN) | 
| 35   return base::SysWideToUTF8(plugin.path.BaseName().value()); | 39   return base::SysWideToUTF8(plugin.path.BaseName().value()); | 
| 36 #endif | 40 #endif | 
| 37 } | 41 } | 
| 38 | 42 | 
| 39 // Gets the plug-in group name as the plug-in name if it is not empty or | 43 // Gets the plug-in group name as the plug-in name if it is not empty or | 
| 40 // the filename without extension if the name is empty. | 44 // the filename without extension if the name is empty. | 
| 41 static string16 GetGroupName(const webkit::WebPluginInfo& plugin) { | 45 static string16 GetGroupName(const webkit::WebPluginInfo& plugin) { | 
| 42   if (!plugin.name.empty()) | 46   if (!plugin.name.empty()) | 
| 43     return plugin.name; | 47     return plugin.name; | 
| 44 | 48 | 
| 45   FilePath::StringType path = plugin.path.BaseName().RemoveExtension().value(); | 49   FilePath::StringType path = plugin.path.BaseName().RemoveExtension().value(); | 
| 46 #if defined(OS_POSIX) | 50 #if defined(OS_POSIX) | 
| 47   return UTF8ToUTF16(path); | 51   return UTF8ToUTF16(path); | 
| 48 #elif defined(OS_WIN) | 52 #elif defined(OS_WIN) | 
| 49   return WideToUTF16(path); | 53   return WideToUTF16(path); | 
| 50 #endif | 54 #endif | 
| 51 } | 55 } | 
| 52 | 56 | 
| 53 // A callback barrier used to enforce the execution of a callback function |  | 
| 54 // only when two different asynchronous callbacks are done execution. |  | 
| 55 // The first asynchronous callback gets a PluginFinder instance and the |  | 
| 56 // second asynchronous callback gets a list of plugins. |  | 
| 57 class PluginFinderCallbackBarrier |  | 
| 58     : public base::RefCountedThreadSafe<PluginFinderCallbackBarrier> { |  | 
| 59  public: |  | 
| 60   typedef base::Callback<void(const PluginFinder::PluginVector&)> |  | 
| 61       PluginsCallback; |  | 
| 62 |  | 
| 63   explicit PluginFinderCallbackBarrier( |  | 
| 64       const PluginFinder::CombinedCallback& callback) |  | 
| 65       : callback_(callback), |  | 
| 66         finder_(NULL) { |  | 
| 67     DCHECK(!callback_.is_null()); |  | 
| 68   } |  | 
| 69 |  | 
| 70   base::Callback<void(PluginFinder*)> CreatePluginFinderCallback() { |  | 
| 71     return base::Bind(&PluginFinderCallbackBarrier::GotPluginFinder, this); |  | 
| 72   } |  | 
| 73 |  | 
| 74   PluginsCallback CreatePluginsCallback() { |  | 
| 75     return base::Bind(&PluginFinderCallbackBarrier::GotPlugins, this); |  | 
| 76   } |  | 
| 77 |  | 
| 78  private: |  | 
| 79   friend class base::RefCountedThreadSafe<PluginFinderCallbackBarrier>; |  | 
| 80 |  | 
| 81   ~PluginFinderCallbackBarrier() { |  | 
| 82     DCHECK(callback_.is_null()); |  | 
| 83   } |  | 
| 84 |  | 
| 85   void GotPlugins(const PluginFinder::PluginVector& plugins) { |  | 
| 86     plugins_.reset(new PluginFinder::PluginVector(plugins)); |  | 
| 87     MaybeRunCallback(); |  | 
| 88   } |  | 
| 89 |  | 
| 90   void GotPluginFinder(PluginFinder* finder) { |  | 
| 91     finder_ = finder; |  | 
| 92     MaybeRunCallback(); |  | 
| 93   } |  | 
| 94 |  | 
| 95   // Executes the callback only when both asynchronous methods have finished |  | 
| 96   // their executions. This is identified by having non-null values in both |  | 
| 97   // |finder_| and |plugins_|. |  | 
| 98   void MaybeRunCallback() { |  | 
| 99     if (!finder_ || !plugins_.get()) |  | 
| 100       return; |  | 
| 101 |  | 
| 102     callback_.Run(*plugins_, finder_); |  | 
| 103     callback_.Reset(); |  | 
| 104   } |  | 
| 105 |  | 
| 106   PluginFinder::CombinedCallback callback_; |  | 
| 107   PluginFinder* finder_; |  | 
| 108   scoped_ptr<PluginFinder::PluginVector> plugins_; |  | 
| 109 }; |  | 
| 110 |  | 
| 111 }  // namespace | 57 }  // namespace | 
| 112 | 58 | 
| 113 // static | 59 // TODO(ibraaaa): DELETE. http://crbug.com/124396 | 
| 114 void PluginFinder::GetPluginsAndPluginFinder( |  | 
| 115     const PluginFinder::CombinedCallback& cb) { |  | 
| 116   scoped_refptr<PluginFinderCallbackBarrier> barrier = |  | 
| 117       new PluginFinderCallbackBarrier(cb); |  | 
| 118 |  | 
| 119   PluginFinder::Get(barrier->CreatePluginFinderCallback()); |  | 
| 120   PluginService::GetInstance()->GetPlugins(barrier->CreatePluginsCallback()); |  | 
| 121 } |  | 
| 122 |  | 
| 123 // static | 60 // static | 
| 124 void PluginFinder::Get(const base::Callback<void(PluginFinder*)>& cb) { | 61 void PluginFinder::Get(const base::Callback<void(PluginFinder*)>& cb) { | 
| 125   // At a later point we might want to do intialization here that needs to be | 62   // At a later point we might want to do intialization here that needs to be | 
| 126   // done asynchronously, like loading the plug-in list from disk or from a URL. | 63   // done asynchronously, like loading the plug-in list from disk or from a URL. | 
| 127   MessageLoop::current()->PostTask(FROM_HERE, base::Bind(cb, GetInstance())); | 64   MessageLoop::current()->PostTask(FROM_HERE, base::Bind(cb, GetInstance())); | 
| 128 } | 65 } | 
| 129 | 66 | 
| 130 // static | 67 // static | 
| 131 PluginFinder* PluginFinder::GetInstance() { | 68 PluginFinder* PluginFinder::GetInstance() { | 
| 132   // PluginFinder::GetInstance() is the only method that's allowed to call | 69   // PluginFinder::GetInstance() is the only method that's allowed to call | 
| 133   // Singleton<PluginFinder>::get(). | 70   // Singleton<PluginFinder>::get(). | 
| 134   return Singleton<PluginFinder>::get(); | 71   return Singleton<PluginFinder>::get(); | 
| 135 } | 72 } | 
| 136 | 73 | 
| 137 PluginFinder::PluginFinder() : plugin_list_(LoadPluginList()) { | 74 PluginFinder::PluginFinder() { | 
|  | 75   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 
|  | 76 } | 
|  | 77 | 
|  | 78 // TODO(ibraaaa): initialize |plugin_list_| from Local State. | 
|  | 79 // http://crbug.com/124396 | 
|  | 80 void PluginFinder::Init() { | 
|  | 81   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 
|  | 82   plugin_list_.reset(LoadPluginList()); | 
| 138   if (!plugin_list_.get()) | 83   if (!plugin_list_.get()) | 
| 139     plugin_list_.reset(new DictionaryValue()); | 84     plugin_list_.reset(new DictionaryValue()); | 
|  | 85 | 
|  | 86   for (DictionaryValue::Iterator plugin_it(*plugin_list_); | 
|  | 87       plugin_it.HasNext(); plugin_it.Advance()) { | 
|  | 88     DictionaryValue* plugin = NULL; | 
|  | 89     const std::string& identifier = plugin_it.key(); | 
|  | 90     if (plugin_list_->GetDictionaryWithoutPathExpansion(identifier, &plugin)) { | 
|  | 91       PluginMetadata* metadata = CreatePluginMetadata(identifier, plugin); | 
|  | 92       identifier_plugin_[identifier] = metadata; | 
|  | 93 | 
|  | 94 #if defined(ENABLE_PLUGIN_INSTALLATION) | 
|  | 95       installers_[identifier] = new PluginInstaller(metadata); | 
|  | 96 #endif | 
|  | 97     } | 
|  | 98   } | 
| 140 } | 99 } | 
| 141 | 100 | 
| 142 // static | 101 // static | 
| 143 DictionaryValue* PluginFinder::LoadPluginList() { | 102 DictionaryValue* PluginFinder::LoadPluginList() { | 
| 144 #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) | 103 #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) | 
| 145   base::StringPiece json_resource( | 104   base::StringPiece json_resource( | 
| 146       ResourceBundle::GetSharedInstance().GetRawDataResource( | 105       ResourceBundle::GetSharedInstance().GetRawDataResource( | 
| 147           IDR_PLUGIN_DB_JSON, ui::SCALE_FACTOR_NONE)); | 106           IDR_PLUGIN_DB_JSON, ui::SCALE_FACTOR_NONE)); | 
| 148   std::string error_str; | 107   std::string error_str; | 
| 149   scoped_ptr<base::Value> value(base::JSONReader::ReadAndReturnError( | 108   scoped_ptr<base::Value> value(base::JSONReader::ReadAndReturnError( | 
| 150       json_resource, | 109       json_resource, | 
| 151       base::JSON_PARSE_RFC, | 110       base::JSON_PARSE_RFC, | 
| 152       NULL, | 111       NULL, | 
| 153       &error_str)); | 112       &error_str)); | 
| 154   if (!value.get()) { | 113   if (!value.get()) { | 
| 155     DLOG(ERROR) << error_str; | 114     DLOG(ERROR) << error_str; | 
| 156     return NULL; | 115     return NULL; | 
| 157   } | 116   } | 
| 158   if (value->GetType() != base::Value::TYPE_DICTIONARY) | 117   if (value->GetType() != base::Value::TYPE_DICTIONARY) | 
| 159     return NULL; | 118     return NULL; | 
| 160   return static_cast<base::DictionaryValue*>(value.release()); | 119   return static_cast<base::DictionaryValue*>(value.release()); | 
| 161 #else | 120 #else | 
| 162   return new DictionaryValue(); | 121   return new DictionaryValue(); | 
| 163 #endif | 122 #endif | 
| 164 } | 123 } | 
| 165 | 124 | 
| 166 PluginFinder::~PluginFinder() { | 125 PluginFinder::~PluginFinder() { | 
|  | 126 #if defined(ENABLE_PLUGIN_INSTALLATION) | 
| 167   STLDeleteValues(&installers_); | 127   STLDeleteValues(&installers_); | 
|  | 128 #endif | 
|  | 129   STLDeleteValues(&identifier_plugin_); | 
| 168 } | 130 } | 
| 169 | 131 | 
|  | 132 #if defined(ENABLE_PLUGIN_INSTALLATION) | 
| 170 PluginInstaller* PluginFinder::FindPlugin(const std::string& mime_type, | 133 PluginInstaller* PluginFinder::FindPlugin(const std::string& mime_type, | 
| 171                                           const std::string& language) { | 134                                           const std::string& language) { | 
| 172   if (g_browser_process->local_state()->GetBoolean(prefs::kDisablePluginFinder)) | 135   if (g_browser_process->local_state()->GetBoolean(prefs::kDisablePluginFinder)) | 
| 173     return NULL; | 136     return NULL; | 
| 174   for (DictionaryValue::Iterator plugin_it(*plugin_list_); | 137   for (DictionaryValue::Iterator plugin_it(*plugin_list_); | 
| 175        plugin_it.HasNext(); plugin_it.Advance()) { | 138        plugin_it.HasNext(); plugin_it.Advance()) { | 
| 176     const DictionaryValue* plugin = NULL; | 139     const DictionaryValue* plugin = NULL; | 
| 177     if (!plugin_it.value().GetAsDictionary(&plugin)) { | 140     if (!plugin_it.value().GetAsDictionary(&plugin)) { | 
| 178       NOTREACHED(); | 141       NOTREACHED(); | 
| 179       continue; | 142       continue; | 
| 180     } | 143     } | 
| 181     std::string language_str; | 144     std::string language_str; | 
| 182     bool success = plugin->GetString("lang", &language_str); | 145     bool success = plugin->GetString("lang", &language_str); | 
| 183     if (language_str != language) | 146     if (language_str != language) | 
| 184       continue; | 147       continue; | 
| 185     const ListValue* mime_types = NULL; | 148     const ListValue* mime_types = NULL; | 
| 186     plugin->GetList("mime_types", &mime_types); | 149     plugin->GetList("mime_types", &mime_types); | 
| 187     DCHECK(success); | 150     DCHECK(success); | 
| 188     for (ListValue::const_iterator mime_type_it = mime_types->begin(); | 151     for (ListValue::const_iterator mime_type_it = mime_types->begin(); | 
| 189          mime_type_it != mime_types->end(); ++mime_type_it) { | 152          mime_type_it != mime_types->end(); ++mime_type_it) { | 
| 190       std::string mime_type_str; | 153       std::string mime_type_str; | 
| 191       success = (*mime_type_it)->GetAsString(&mime_type_str); | 154       success = (*mime_type_it)->GetAsString(&mime_type_str); | 
| 192       DCHECK(success); | 155       DCHECK(success); | 
| 193       if (mime_type_str == mime_type) { | 156       if (mime_type_str == mime_type) { | 
| 194         std::string identifier = plugin_it.key(); | 157         std::string identifier = plugin_it.key(); | 
| 195         std::map<std::string, PluginInstaller*>::const_iterator installer = | 158         { | 
| 196             installers_.find(identifier); | 159           base::AutoLock lock(mutex_); | 
| 197         if (installer != installers_.end()) | 160           std::map<std::string, PluginInstaller*>::const_iterator installer = | 
|  | 161               installers_.find(identifier); | 
|  | 162           DCHECK(installer != installers_.end()); | 
| 198           return installer->second; | 163           return installer->second; | 
| 199         return CreateInstaller(identifier, plugin); | 164         } | 
| 200       } | 165       } | 
| 201     } | 166     } | 
| 202   } | 167   } | 
| 203   return NULL; | 168   return NULL; | 
| 204 } | 169 } | 
| 205 | 170 | 
| 206 PluginInstaller* PluginFinder::FindPluginWithIdentifier( | 171 PluginInstaller* PluginFinder::FindPluginWithIdentifier( | 
| 207     const std::string& identifier) { | 172     const std::string& identifier) { | 
|  | 173   base::AutoLock lock(mutex_); | 
| 208   std::map<std::string, PluginInstaller*>::const_iterator it = | 174   std::map<std::string, PluginInstaller*>::const_iterator it = | 
| 209       installers_.find(identifier); | 175       installers_.find(identifier); | 
| 210   if (it != installers_.end()) | 176   if (it != installers_.end()) | 
| 211     return it->second; | 177     return it->second; | 
| 212   DictionaryValue* plugin = NULL; | 178 | 
| 213   if (plugin_list_->GetDictionaryWithoutPathExpansion(identifier, &plugin)) | 179   return NULL; | 
| 214     return CreateInstaller(identifier, plugin); | 180 } | 
|  | 181 #endif | 
|  | 182 | 
|  | 183 PluginMetadata* PluginFinder::FindPluginMetadataWithIdentifier( | 
|  | 184     const std::string& identifier) { | 
|  | 185   base::AutoLock lock(mutex_); | 
|  | 186   std::map<std::string, PluginMetadata*>::const_iterator it = | 
|  | 187       identifier_plugin_.find(identifier); | 
|  | 188   if (it != identifier_plugin_.end()) | 
|  | 189     return it->second; | 
|  | 190 | 
| 215   return NULL; | 191   return NULL; | 
| 216 } | 192 } | 
| 217 | 193 | 
| 218 PluginInstaller* PluginFinder::CreateInstaller( | 194 PluginMetadata* PluginFinder::CreatePluginMetadata( | 
| 219     const std::string& identifier, | 195     const std::string& identifier, | 
| 220     const DictionaryValue* plugin_dict) { | 196     const DictionaryValue* plugin_dict) { | 
| 221   DCHECK(!installers_[identifier]); | 197   DCHECK(!identifier_plugin_[identifier]); | 
| 222   std::string url; | 198   std::string url; | 
| 223   bool success = plugin_dict->GetString("url", &url); | 199   bool success = plugin_dict->GetString("url", &url); | 
| 224   std::string help_url; | 200   std::string help_url; | 
| 225   plugin_dict->GetString("help_url", &help_url); | 201   plugin_dict->GetString("help_url", &help_url); | 
| 226   string16 name; | 202   string16 name; | 
| 227   success = plugin_dict->GetString("name", &name); | 203   success = plugin_dict->GetString("name", &name); | 
| 228   DCHECK(success); | 204   DCHECK(success); | 
| 229   bool display_url = false; | 205   bool display_url = false; | 
| 230   plugin_dict->GetBoolean("displayurl", &display_url); | 206   plugin_dict->GetBoolean("displayurl", &display_url); | 
| 231   string16 group_name_matcher; | 207   string16 group_name_matcher; | 
| 232   success = plugin_dict->GetString("group_name_matcher", &group_name_matcher); | 208   success = plugin_dict->GetString("group_name_matcher", &group_name_matcher); | 
| 233   DCHECK(success); | 209   DCHECK(success); | 
| 234 | 210 | 
| 235   PluginInstaller* installer = new PluginInstaller(identifier, | 211   PluginMetadata* plugin = new PluginMetadata(identifier, | 
| 236                                                    name, | 212                                               name, | 
| 237                                                    display_url, | 213                                               display_url, | 
| 238                                                    GURL(url), | 214                                               GURL(url), | 
| 239                                                    GURL(help_url), | 215                                               GURL(help_url), | 
| 240                                                    group_name_matcher); | 216                                               group_name_matcher); | 
| 241   const ListValue* versions = NULL; | 217   const ListValue* versions = NULL; | 
| 242   if (plugin_dict->GetList("versions", &versions)) { | 218   if (plugin_dict->GetList("versions", &versions)) { | 
| 243     for (ListValue::const_iterator it = versions->begin(); | 219     for (ListValue::const_iterator it = versions->begin(); | 
| 244          it != versions->end(); ++it) { | 220          it != versions->end(); ++it) { | 
| 245       DictionaryValue* version_dict = NULL; | 221       DictionaryValue* version_dict = NULL; | 
| 246       if (!(*it)->GetAsDictionary(&version_dict)) { | 222       if (!(*it)->GetAsDictionary(&version_dict)) { | 
| 247         NOTREACHED(); | 223         NOTREACHED(); | 
| 248         continue; | 224         continue; | 
| 249       } | 225       } | 
| 250       std::string version; | 226       std::string version; | 
| 251       success = version_dict->GetString("version", &version); | 227       success = version_dict->GetString("version", &version); | 
| 252       DCHECK(success); | 228       DCHECK(success); | 
| 253       std::string status_str; | 229       std::string status_str; | 
| 254       success = version_dict->GetString("status", &status_str); | 230       success = version_dict->GetString("status", &status_str); | 
| 255       DCHECK(success); | 231       DCHECK(success); | 
| 256       PluginInstaller::SecurityStatus status = | 232       PluginMetadata::SecurityStatus status = | 
| 257           PluginInstaller::SECURITY_STATUS_UP_TO_DATE; | 233           PluginMetadata::SECURITY_STATUS_UP_TO_DATE; | 
| 258       success = PluginInstaller::ParseSecurityStatus(status_str, &status); | 234       success = PluginMetadata::ParseSecurityStatus(status_str, &status); | 
| 259       DCHECK(success); | 235       DCHECK(success); | 
| 260       installer->AddVersion(Version(version), status); | 236       plugin->AddVersion(Version(version), status); | 
| 261     } | 237     } | 
| 262   } | 238   } | 
| 263 | 239 | 
| 264   installers_[identifier] = installer; | 240   return plugin; | 
| 265   return installer; |  | 
| 266 } | 241 } | 
| 267 | 242 | 
| 268 PluginInstaller* PluginFinder::GetPluginInstaller( | 243 PluginMetadata* PluginFinder::GetPluginMetadata( | 
| 269     const webkit::WebPluginInfo& plugin) { | 244     const webkit::WebPluginInfo& plugin) { | 
| 270   if (name_installers_.find(plugin.name) != name_installers_.end()) | 245   base::AutoLock lock(mutex_); | 
| 271     return name_installers_[plugin.name]; | 246   if (name_plugin_.find(plugin.name) != name_plugin_.end()) | 
|  | 247     return name_plugin_[plugin.name]; | 
| 272 | 248 | 
| 273   for (DictionaryValue::Iterator plugin_it(*plugin_list_); | 249   // Use the group name matcher to find the plug-in metadata we want. | 
| 274        plugin_it.HasNext(); plugin_it.Advance()) { | 250   for (std::map<std::string, PluginMetadata*>::const_iterator it = | 
| 275     // This method triggers the lazy initialization for all PluginInstallers. | 251       identifier_plugin_.begin(); it != identifier_plugin_.end(); ++it) { | 
| 276     FindPluginWithIdentifier(plugin_it.key()); |  | 
| 277   } |  | 
| 278 |  | 
| 279   // Use the group name matcher to find the plug-in installer we want. |  | 
| 280   for (std::map<std::string, PluginInstaller*>::const_iterator it = |  | 
| 281       installers_.begin(); it != installers_.end(); ++it) { |  | 
| 282     if (!it->second->MatchesPlugin(plugin)) | 252     if (!it->second->MatchesPlugin(plugin)) | 
| 283       continue; | 253       continue; | 
| 284 | 254 | 
| 285     name_installers_[plugin.name] = it->second; | 255     name_plugin_[plugin.name] = it->second; | 
| 286     return it->second; | 256     return it->second; | 
| 287   } | 257   } | 
| 288 | 258 | 
| 289   // The plug-in installer was not found, create a dummy one holding | 259   // The plug-in metadata was not found, create a dummy one holding | 
| 290   // the name, identifier and group name only. | 260   // the name, identifier and group name only. | 
| 291   std::string identifier = GetIdentifier(plugin); | 261   std::string identifier = GetIdentifier(plugin); | 
| 292   PluginInstaller* installer = new PluginInstaller(identifier, | 262   PluginMetadata* metadata = new PluginMetadata(identifier, | 
| 293                                                    GetGroupName(plugin), | 263                                                 GetGroupName(plugin), | 
| 294                                                    false, GURL(), GURL(), | 264                                                 false, GURL(), GURL(), | 
| 295                                                    GetGroupName(plugin)); | 265                                                 GetGroupName(plugin)); | 
| 296   installers_[identifier] = installer; | 266 | 
| 297   name_installers_[plugin.name] = installer; | 267   name_plugin_[plugin.name] = metadata; | 
| 298   return installer; | 268   identifier_plugin_[identifier] = metadata; | 
|  | 269   return metadata; | 
| 299 } | 270 } | 
| OLD | NEW | 
|---|