| 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 "content/browser/plugin_service_impl.h" | 5 #include "content/browser/plugin_service_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/file_path.h" | 10 #include "base/file_path.h" |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 #if defined(OS_MACOSX) | 73 #if defined(OS_MACOSX) |
| 74 void NotifyPluginsOfActivation() { | 74 void NotifyPluginsOfActivation() { |
| 75 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 75 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 76 | 76 |
| 77 for (PluginProcessHostIterator iter; !iter.Done(); ++iter) | 77 for (PluginProcessHostIterator iter; !iter.Done(); ++iter) |
| 78 iter->OnAppActivation(); | 78 iter->OnAppActivation(); |
| 79 } | 79 } |
| 80 #endif | 80 #endif |
| 81 | 81 |
| 82 #if defined(OS_POSIX) && !defined(OS_OPENBSD) && !defined(OS_ANDROID) | 82 #if defined(OS_POSIX) && !defined(OS_OPENBSD) && !defined(OS_ANDROID) |
| 83 void NotifyPluginDirChanged(const FilePath& path, bool error) { | 83 void NotifyPluginDirChanged(const base::FilePath& path, bool error) { |
| 84 if (error) { | 84 if (error) { |
| 85 // TODO(pastarmovj): Add some sensible error handling. Maybe silently | 85 // TODO(pastarmovj): Add some sensible error handling. Maybe silently |
| 86 // stopping the watcher would be enough. Or possibly restart it. | 86 // stopping the watcher would be enough. Or possibly restart it. |
| 87 NOTREACHED(); | 87 NOTREACHED(); |
| 88 return; | 88 return; |
| 89 } | 89 } |
| 90 VLOG(1) << "Watched path changed: " << path.value(); | 90 VLOG(1) << "Watched path changed: " << path.value(); |
| 91 // Make the plugin list update itself | 91 // Make the plugin list update itself |
| 92 webkit::npapi::PluginList::Singleton()->RefreshPlugins(); | 92 webkit::npapi::PluginList::Singleton()->RefreshPlugins(); |
| 93 BrowserThread::PostTask( | 93 BrowserThread::PostTask( |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 | 147 |
| 148 RegisterPepperPlugins(); | 148 RegisterPepperPlugins(); |
| 149 | 149 |
| 150 // The --site-per-process flag enables an out-of-process iframes | 150 // The --site-per-process flag enables an out-of-process iframes |
| 151 // prototype, which uses WebView for rendering. We need to register the MIME | 151 // prototype, which uses WebView for rendering. We need to register the MIME |
| 152 // type we use with the plugin, so the renderer can instantiate it. | 152 // type we use with the plugin, so the renderer can instantiate it. |
| 153 const CommandLine* command_line = CommandLine::ForCurrentProcess(); | 153 const CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| 154 if (command_line->HasSwitch(switches::kSitePerProcess)) { | 154 if (command_line->HasSwitch(switches::kSitePerProcess)) { |
| 155 webkit::WebPluginInfo webview_plugin( | 155 webkit::WebPluginInfo webview_plugin( |
| 156 ASCIIToUTF16("WebView Tag"), | 156 ASCIIToUTF16("WebView Tag"), |
| 157 FilePath(FILE_PATH_LITERAL("")), | 157 base::FilePath(FILE_PATH_LITERAL("")), |
| 158 ASCIIToUTF16("1.2.3.4"), | 158 ASCIIToUTF16("1.2.3.4"), |
| 159 ASCIIToUTF16("Browser Plugin.")); | 159 ASCIIToUTF16("Browser Plugin.")); |
| 160 webview_plugin.type = webkit::WebPluginInfo::PLUGIN_TYPE_NPAPI; | 160 webview_plugin.type = webkit::WebPluginInfo::PLUGIN_TYPE_NPAPI; |
| 161 webkit::WebPluginMimeType webview_plugin_mime_type; | 161 webkit::WebPluginMimeType webview_plugin_mime_type; |
| 162 webview_plugin_mime_type.mime_type = "application/browser-plugin"; | 162 webview_plugin_mime_type.mime_type = "application/browser-plugin"; |
| 163 webview_plugin_mime_type.file_extensions.push_back("*"); | 163 webview_plugin_mime_type.file_extensions.push_back("*"); |
| 164 webview_plugin.mime_types.push_back(webview_plugin_mime_type); | 164 webview_plugin.mime_types.push_back(webview_plugin_mime_type); |
| 165 RegisterInternalPlugin(webview_plugin, true); | 165 RegisterInternalPlugin(webview_plugin, true); |
| 166 } | 166 } |
| 167 | 167 |
| 168 GetContentClient()->AddNPAPIPlugins(plugin_list_); | 168 GetContentClient()->AddNPAPIPlugins(plugin_list_); |
| 169 | 169 |
| 170 // Load any specified on the command line as well. | 170 // Load any specified on the command line as well. |
| 171 FilePath path = command_line->GetSwitchValuePath(switches::kLoadPlugin); | 171 base::FilePath path = |
| 172 command_line->GetSwitchValuePath(switches::kLoadPlugin); |
| 172 if (!path.empty()) | 173 if (!path.empty()) |
| 173 AddExtraPluginPath(path); | 174 AddExtraPluginPath(path); |
| 174 path = command_line->GetSwitchValuePath(switches::kExtraPluginDir); | 175 path = command_line->GetSwitchValuePath(switches::kExtraPluginDir); |
| 175 if (!path.empty()) | 176 if (!path.empty()) |
| 176 plugin_list_->AddExtraPluginDir(path); | 177 plugin_list_->AddExtraPluginDir(path); |
| 177 } | 178 } |
| 178 | 179 |
| 179 void PluginServiceImpl::StartWatchingPlugins() { | 180 void PluginServiceImpl::StartWatchingPlugins() { |
| 180 // Start watching for changes in the plugin list. This means watching | 181 // Start watching for changes in the plugin list. This means watching |
| 181 // for changes in the Windows registry keys and on both Windows and POSIX | 182 // for changes in the Windows registry keys and on both Windows and POSIX |
| (...skipping 21 matching lines...) Expand all Loading... |
| 203 hklm_watcher_.StartWatching(hklm_event_.get(), callback); | 204 hklm_watcher_.StartWatching(hklm_event_.get(), callback); |
| 204 } | 205 } |
| 205 } | 206 } |
| 206 #endif | 207 #endif |
| 207 #if defined(OS_POSIX) && !defined(OS_OPENBSD) && !defined(OS_ANDROID) | 208 #if defined(OS_POSIX) && !defined(OS_OPENBSD) && !defined(OS_ANDROID) |
| 208 // On ChromeOS the user can't install plugins anyway and on Windows all | 209 // On ChromeOS the user can't install plugins anyway and on Windows all |
| 209 // important plugins register themselves in the registry so no need to do that. | 210 // important plugins register themselves in the registry so no need to do that. |
| 210 | 211 |
| 211 // Get the list of all paths for registering the FilePathWatchers | 212 // Get the list of all paths for registering the FilePathWatchers |
| 212 // that will track and if needed reload the list of plugins on runtime. | 213 // that will track and if needed reload the list of plugins on runtime. |
| 213 std::vector<FilePath> plugin_dirs; | 214 std::vector<base::FilePath> plugin_dirs; |
| 214 plugin_list_->GetPluginDirectories(&plugin_dirs); | 215 plugin_list_->GetPluginDirectories(&plugin_dirs); |
| 215 | 216 |
| 216 for (size_t i = 0; i < plugin_dirs.size(); ++i) { | 217 for (size_t i = 0; i < plugin_dirs.size(); ++i) { |
| 217 // FilePathWatcher can not handle non-absolute paths under windows. | 218 // FilePathWatcher can not handle non-absolute paths under windows. |
| 218 // We don't watch for file changes in windows now but if this should ever | 219 // We don't watch for file changes in windows now but if this should ever |
| 219 // be extended to Windows these lines might save some time of debugging. | 220 // be extended to Windows these lines might save some time of debugging. |
| 220 #if defined(OS_WIN) | 221 #if defined(OS_WIN) |
| 221 if (!plugin_dirs[i].IsAbsolute()) | 222 if (!plugin_dirs[i].IsAbsolute()) |
| 222 continue; | 223 continue; |
| 223 #endif | 224 #endif |
| 224 FilePathWatcher* watcher = new FilePathWatcher(); | 225 FilePathWatcher* watcher = new FilePathWatcher(); |
| 225 VLOG(1) << "Watching for changes in: " << plugin_dirs[i].value(); | 226 VLOG(1) << "Watching for changes in: " << plugin_dirs[i].value(); |
| 226 BrowserThread::PostTask( | 227 BrowserThread::PostTask( |
| 227 BrowserThread::FILE, FROM_HERE, | 228 BrowserThread::FILE, FROM_HERE, |
| 228 base::Bind(&PluginServiceImpl::RegisterFilePathWatcher, watcher, | 229 base::Bind(&PluginServiceImpl::RegisterFilePathWatcher, watcher, |
| 229 plugin_dirs[i])); | 230 plugin_dirs[i])); |
| 230 file_watchers_.push_back(watcher); | 231 file_watchers_.push_back(watcher); |
| 231 } | 232 } |
| 232 #endif | 233 #endif |
| 233 } | 234 } |
| 234 | 235 |
| 235 PluginProcessHost* PluginServiceImpl::FindNpapiPluginProcess( | 236 PluginProcessHost* PluginServiceImpl::FindNpapiPluginProcess( |
| 236 const FilePath& plugin_path) { | 237 const base::FilePath& plugin_path) { |
| 237 for (PluginProcessHostIterator iter; !iter.Done(); ++iter) { | 238 for (PluginProcessHostIterator iter; !iter.Done(); ++iter) { |
| 238 if (iter->info().path == plugin_path) | 239 if (iter->info().path == plugin_path) |
| 239 return *iter; | 240 return *iter; |
| 240 } | 241 } |
| 241 | 242 |
| 242 return NULL; | 243 return NULL; |
| 243 } | 244 } |
| 244 | 245 |
| 245 PpapiPluginProcessHost* PluginServiceImpl::FindPpapiPluginProcess( | 246 PpapiPluginProcessHost* PluginServiceImpl::FindPpapiPluginProcess( |
| 246 const FilePath& plugin_path, | 247 const base::FilePath& plugin_path, |
| 247 const FilePath& profile_data_directory) { | 248 const base::FilePath& profile_data_directory) { |
| 248 for (PpapiPluginProcessHostIterator iter; !iter.Done(); ++iter) { | 249 for (PpapiPluginProcessHostIterator iter; !iter.Done(); ++iter) { |
| 249 if (iter->plugin_path() == plugin_path && | 250 if (iter->plugin_path() == plugin_path && |
| 250 iter->profile_data_directory() == profile_data_directory) { | 251 iter->profile_data_directory() == profile_data_directory) { |
| 251 return *iter; | 252 return *iter; |
| 252 } | 253 } |
| 253 } | 254 } |
| 254 return NULL; | 255 return NULL; |
| 255 } | 256 } |
| 256 | 257 |
| 257 PpapiPluginProcessHost* PluginServiceImpl::FindPpapiBrokerProcess( | 258 PpapiPluginProcessHost* PluginServiceImpl::FindPpapiBrokerProcess( |
| 258 const FilePath& broker_path) { | 259 const base::FilePath& broker_path) { |
| 259 for (PpapiBrokerProcessHostIterator iter; !iter.Done(); ++iter) { | 260 for (PpapiBrokerProcessHostIterator iter; !iter.Done(); ++iter) { |
| 260 if (iter->plugin_path() == broker_path) | 261 if (iter->plugin_path() == broker_path) |
| 261 return *iter; | 262 return *iter; |
| 262 } | 263 } |
| 263 | 264 |
| 264 return NULL; | 265 return NULL; |
| 265 } | 266 } |
| 266 | 267 |
| 267 PluginProcessHost* PluginServiceImpl::FindOrStartNpapiPluginProcess( | 268 PluginProcessHost* PluginServiceImpl::FindOrStartNpapiPluginProcess( |
| 268 int render_process_id, | 269 int render_process_id, |
| 269 const FilePath& plugin_path) { | 270 const base::FilePath& plugin_path) { |
| 270 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 271 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 271 | 272 |
| 272 if (filter_ && !filter_->CanLoadPlugin(render_process_id, plugin_path)) | 273 if (filter_ && !filter_->CanLoadPlugin(render_process_id, plugin_path)) |
| 273 return NULL; | 274 return NULL; |
| 274 | 275 |
| 275 PluginProcessHost* plugin_host = FindNpapiPluginProcess(plugin_path); | 276 PluginProcessHost* plugin_host = FindNpapiPluginProcess(plugin_path); |
| 276 if (plugin_host) | 277 if (plugin_host) |
| 277 return plugin_host; | 278 return plugin_host; |
| 278 | 279 |
| 279 webkit::WebPluginInfo info; | 280 webkit::WebPluginInfo info; |
| 280 if (!GetPluginInfoByPath(plugin_path, &info)) { | 281 if (!GetPluginInfoByPath(plugin_path, &info)) { |
| 281 return NULL; | 282 return NULL; |
| 282 } | 283 } |
| 283 | 284 |
| 284 // This plugin isn't loaded by any plugin process, so create a new process. | 285 // This plugin isn't loaded by any plugin process, so create a new process. |
| 285 scoped_ptr<PluginProcessHost> new_host(new PluginProcessHost()); | 286 scoped_ptr<PluginProcessHost> new_host(new PluginProcessHost()); |
| 286 if (!new_host->Init(info)) { | 287 if (!new_host->Init(info)) { |
| 287 NOTREACHED(); // Init is not expected to fail. | 288 NOTREACHED(); // Init is not expected to fail. |
| 288 return NULL; | 289 return NULL; |
| 289 } | 290 } |
| 290 return new_host.release(); | 291 return new_host.release(); |
| 291 } | 292 } |
| 292 | 293 |
| 293 PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiPluginProcess( | 294 PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiPluginProcess( |
| 294 int render_process_id, | 295 int render_process_id, |
| 295 const FilePath& plugin_path, | 296 const base::FilePath& plugin_path, |
| 296 const FilePath& profile_data_directory, | 297 const base::FilePath& profile_data_directory, |
| 297 PpapiPluginProcessHost::PluginClient* client) { | 298 PpapiPluginProcessHost::PluginClient* client) { |
| 298 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 299 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 299 | 300 |
| 300 if (filter_ && !filter_->CanLoadPlugin(render_process_id, plugin_path)) | 301 if (filter_ && !filter_->CanLoadPlugin(render_process_id, plugin_path)) |
| 301 return NULL; | 302 return NULL; |
| 302 | 303 |
| 303 PpapiPluginProcessHost* plugin_host = | 304 PpapiPluginProcessHost* plugin_host = |
| 304 FindPpapiPluginProcess(plugin_path, profile_data_directory); | 305 FindPpapiPluginProcess(plugin_path, profile_data_directory); |
| 305 if (plugin_host) | 306 if (plugin_host) |
| 306 return plugin_host; | 307 return plugin_host; |
| 307 | 308 |
| 308 // Validate that the plugin is actually registered. | 309 // Validate that the plugin is actually registered. |
| 309 PepperPluginInfo* info = GetRegisteredPpapiPluginInfo(plugin_path); | 310 PepperPluginInfo* info = GetRegisteredPpapiPluginInfo(plugin_path); |
| 310 if (!info) | 311 if (!info) |
| 311 return NULL; | 312 return NULL; |
| 312 | 313 |
| 313 // This plugin isn't loaded by any plugin process, so create a new process. | 314 // This plugin isn't loaded by any plugin process, so create a new process. |
| 314 return PpapiPluginProcessHost::CreatePluginHost( | 315 return PpapiPluginProcessHost::CreatePluginHost( |
| 315 *info, profile_data_directory, | 316 *info, profile_data_directory, |
| 316 client->GetResourceContext()->GetHostResolver()); | 317 client->GetResourceContext()->GetHostResolver()); |
| 317 } | 318 } |
| 318 | 319 |
| 319 PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiBrokerProcess( | 320 PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiBrokerProcess( |
| 320 int render_process_id, | 321 int render_process_id, |
| 321 const FilePath& plugin_path) { | 322 const base::FilePath& plugin_path) { |
| 322 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 323 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 323 | 324 |
| 324 if (filter_ && !filter_->CanLoadPlugin(render_process_id, plugin_path)) | 325 if (filter_ && !filter_->CanLoadPlugin(render_process_id, plugin_path)) |
| 325 return NULL; | 326 return NULL; |
| 326 | 327 |
| 327 PpapiPluginProcessHost* plugin_host = FindPpapiBrokerProcess(plugin_path); | 328 PpapiPluginProcessHost* plugin_host = FindPpapiBrokerProcess(plugin_path); |
| 328 if (plugin_host) | 329 if (plugin_host) |
| 329 return plugin_host; | 330 return plugin_host; |
| 330 | 331 |
| 331 // Validate that the plugin is actually registered. | 332 // Validate that the plugin is actually registered. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 358 page_url, | 359 page_url, |
| 359 client->GetResourceContext() | 360 client->GetResourceContext() |
| 360 }; | 361 }; |
| 361 GetPlugins(base::Bind( | 362 GetPlugins(base::Bind( |
| 362 &PluginServiceImpl::ForwardGetAllowedPluginForOpenChannelToPlugin, | 363 &PluginServiceImpl::ForwardGetAllowedPluginForOpenChannelToPlugin, |
| 363 base::Unretained(this), params, url, mime_type, client)); | 364 base::Unretained(this), params, url, mime_type, client)); |
| 364 } | 365 } |
| 365 | 366 |
| 366 void PluginServiceImpl::OpenChannelToPpapiPlugin( | 367 void PluginServiceImpl::OpenChannelToPpapiPlugin( |
| 367 int render_process_id, | 368 int render_process_id, |
| 368 const FilePath& plugin_path, | 369 const base::FilePath& plugin_path, |
| 369 const FilePath& profile_data_directory, | 370 const base::FilePath& profile_data_directory, |
| 370 PpapiPluginProcessHost::PluginClient* client) { | 371 PpapiPluginProcessHost::PluginClient* client) { |
| 371 PpapiPluginProcessHost* plugin_host = FindOrStartPpapiPluginProcess( | 372 PpapiPluginProcessHost* plugin_host = FindOrStartPpapiPluginProcess( |
| 372 render_process_id, plugin_path, profile_data_directory, client); | 373 render_process_id, plugin_path, profile_data_directory, client); |
| 373 if (plugin_host) { | 374 if (plugin_host) { |
| 374 plugin_host->OpenChannelToPlugin(client); | 375 plugin_host->OpenChannelToPlugin(client); |
| 375 } else { | 376 } else { |
| 376 // Send error. | 377 // Send error. |
| 377 client->OnPpapiChannelOpened(IPC::ChannelHandle(), base::kNullProcessId, 0); | 378 client->OnPpapiChannelOpened(IPC::ChannelHandle(), base::kNullProcessId, 0); |
| 378 } | 379 } |
| 379 } | 380 } |
| 380 | 381 |
| 381 void PluginServiceImpl::OpenChannelToPpapiBroker( | 382 void PluginServiceImpl::OpenChannelToPpapiBroker( |
| 382 int render_process_id, | 383 int render_process_id, |
| 383 const FilePath& path, | 384 const base::FilePath& path, |
| 384 PpapiPluginProcessHost::BrokerClient* client) { | 385 PpapiPluginProcessHost::BrokerClient* client) { |
| 385 PpapiPluginProcessHost* plugin_host = FindOrStartPpapiBrokerProcess( | 386 PpapiPluginProcessHost* plugin_host = FindOrStartPpapiBrokerProcess( |
| 386 render_process_id, path); | 387 render_process_id, path); |
| 387 if (plugin_host) { | 388 if (plugin_host) { |
| 388 plugin_host->OpenChannelToPlugin(client); | 389 plugin_host->OpenChannelToPlugin(client); |
| 389 } else { | 390 } else { |
| 390 // Send error. | 391 // Send error. |
| 391 client->OnPpapiChannelOpened(IPC::ChannelHandle(), base::kNullProcessId, 0); | 392 client->OnPpapiChannelOpened(IPC::ChannelHandle(), base::kNullProcessId, 0); |
| 392 } | 393 } |
| 393 } | 394 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 417 const GURL& page_url, | 418 const GURL& page_url, |
| 418 const std::string& mime_type, | 419 const std::string& mime_type, |
| 419 PluginProcessHost::Client* client, | 420 PluginProcessHost::Client* client, |
| 420 ResourceContext* resource_context) { | 421 ResourceContext* resource_context) { |
| 421 webkit::WebPluginInfo info; | 422 webkit::WebPluginInfo info; |
| 422 bool allow_wildcard = true; | 423 bool allow_wildcard = true; |
| 423 bool found = GetPluginInfo( | 424 bool found = GetPluginInfo( |
| 424 render_process_id, render_view_id, resource_context, | 425 render_process_id, render_view_id, resource_context, |
| 425 url, page_url, mime_type, allow_wildcard, | 426 url, page_url, mime_type, allow_wildcard, |
| 426 NULL, &info, NULL); | 427 NULL, &info, NULL); |
| 427 FilePath plugin_path; | 428 base::FilePath plugin_path; |
| 428 if (found) | 429 if (found) |
| 429 plugin_path = info.path; | 430 plugin_path = info.path; |
| 430 | 431 |
| 431 // Now we jump back to the IO thread to finish opening the channel. | 432 // Now we jump back to the IO thread to finish opening the channel. |
| 432 BrowserThread::PostTask( | 433 BrowserThread::PostTask( |
| 433 BrowserThread::IO, FROM_HERE, | 434 BrowserThread::IO, FROM_HERE, |
| 434 base::Bind(&PluginServiceImpl::FinishOpenChannelToPlugin, | 435 base::Bind(&PluginServiceImpl::FinishOpenChannelToPlugin, |
| 435 base::Unretained(this), | 436 base::Unretained(this), |
| 436 render_process_id, | 437 render_process_id, |
| 437 plugin_path, | 438 plugin_path, |
| 438 client)); | 439 client)); |
| 439 } | 440 } |
| 440 | 441 |
| 441 void PluginServiceImpl::FinishOpenChannelToPlugin( | 442 void PluginServiceImpl::FinishOpenChannelToPlugin( |
| 442 int render_process_id, | 443 int render_process_id, |
| 443 const FilePath& plugin_path, | 444 const base::FilePath& plugin_path, |
| 444 PluginProcessHost::Client* client) { | 445 PluginProcessHost::Client* client) { |
| 445 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 446 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 446 | 447 |
| 447 // Make sure it hasn't been canceled yet. | 448 // Make sure it hasn't been canceled yet. |
| 448 if (!ContainsKey(pending_plugin_clients_, client)) | 449 if (!ContainsKey(pending_plugin_clients_, client)) |
| 449 return; | 450 return; |
| 450 pending_plugin_clients_.erase(client); | 451 pending_plugin_clients_.erase(client); |
| 451 | 452 |
| 452 PluginProcessHost* plugin_host = FindOrStartNpapiPluginProcess( | 453 PluginProcessHost* plugin_host = FindOrStartNpapiPluginProcess( |
| 453 render_process_id, plugin_path); | 454 render_process_id, plugin_path); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 497 &plugins[i])) { | 498 &plugins[i])) { |
| 498 *info = plugins[i]; | 499 *info = plugins[i]; |
| 499 if (actual_mime_type) | 500 if (actual_mime_type) |
| 500 *actual_mime_type = mime_types[i]; | 501 *actual_mime_type = mime_types[i]; |
| 501 return true; | 502 return true; |
| 502 } | 503 } |
| 503 } | 504 } |
| 504 return false; | 505 return false; |
| 505 } | 506 } |
| 506 | 507 |
| 507 bool PluginServiceImpl::GetPluginInfoByPath(const FilePath& plugin_path, | 508 bool PluginServiceImpl::GetPluginInfoByPath(const base::FilePath& plugin_path, |
| 508 webkit::WebPluginInfo* info) { | 509 webkit::WebPluginInfo* info) { |
| 509 std::vector<webkit::WebPluginInfo> plugins; | 510 std::vector<webkit::WebPluginInfo> plugins; |
| 510 plugin_list_->GetPluginsNoRefresh(&plugins); | 511 plugin_list_->GetPluginsNoRefresh(&plugins); |
| 511 | 512 |
| 512 for (std::vector<webkit::WebPluginInfo>::iterator it = plugins.begin(); | 513 for (std::vector<webkit::WebPluginInfo>::iterator it = plugins.begin(); |
| 513 it != plugins.end(); | 514 it != plugins.end(); |
| 514 ++it) { | 515 ++it) { |
| 515 if (it->path == plugin_path) { | 516 if (it->path == plugin_path) { |
| 516 *info = *it; | 517 *info = *it; |
| 517 return true; | 518 return true; |
| 518 } | 519 } |
| 519 } | 520 } |
| 520 | 521 |
| 521 return false; | 522 return false; |
| 522 } | 523 } |
| 523 | 524 |
| 524 string16 PluginServiceImpl::GetPluginDisplayNameByPath(const FilePath& path) { | 525 string16 PluginServiceImpl::GetPluginDisplayNameByPath( |
| 526 const base::FilePath& path) { |
| 525 string16 plugin_name = path.LossyDisplayName(); | 527 string16 plugin_name = path.LossyDisplayName(); |
| 526 webkit::WebPluginInfo info; | 528 webkit::WebPluginInfo info; |
| 527 if (PluginService::GetInstance()->GetPluginInfoByPath(path, &info) && | 529 if (PluginService::GetInstance()->GetPluginInfoByPath(path, &info) && |
| 528 !info.name.empty()) { | 530 !info.name.empty()) { |
| 529 plugin_name = info.name; | 531 plugin_name = info.name; |
| 530 #if defined(OS_MACOSX) | 532 #if defined(OS_MACOSX) |
| 531 // Many plugins on the Mac have .plugin in the actual name, which looks | 533 // Many plugins on the Mac have .plugin in the actual name, which looks |
| 532 // terrible, so look for that and strip it off if present. | 534 // terrible, so look for that and strip it off if present. |
| 533 const std::string kPluginExtension = ".plugin"; | 535 const std::string kPluginExtension = ".plugin"; |
| 534 if (EndsWith(plugin_name, ASCIIToUTF16(kPluginExtension), true)) | 536 if (EndsWith(plugin_name, ASCIIToUTF16(kPluginExtension), true)) |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 606 void PluginServiceImpl::RegisterPepperPlugins() { | 608 void PluginServiceImpl::RegisterPepperPlugins() { |
| 607 // TODO(abarth): It seems like the PepperPluginRegistry should do this work. | 609 // TODO(abarth): It seems like the PepperPluginRegistry should do this work. |
| 608 PepperPluginRegistry::ComputeList(&ppapi_plugins_); | 610 PepperPluginRegistry::ComputeList(&ppapi_plugins_); |
| 609 for (size_t i = 0; i < ppapi_plugins_.size(); ++i) { | 611 for (size_t i = 0; i < ppapi_plugins_.size(); ++i) { |
| 610 RegisterInternalPlugin(ppapi_plugins_[i].ToWebPluginInfo(), true); | 612 RegisterInternalPlugin(ppapi_plugins_[i].ToWebPluginInfo(), true); |
| 611 } | 613 } |
| 612 } | 614 } |
| 613 | 615 |
| 614 // There should generally be very few plugins so a brute-force search is fine. | 616 // There should generally be very few plugins so a brute-force search is fine. |
| 615 PepperPluginInfo* PluginServiceImpl::GetRegisteredPpapiPluginInfo( | 617 PepperPluginInfo* PluginServiceImpl::GetRegisteredPpapiPluginInfo( |
| 616 const FilePath& plugin_path) { | 618 const base::FilePath& plugin_path) { |
| 617 PepperPluginInfo* info = NULL; | 619 PepperPluginInfo* info = NULL; |
| 618 for (size_t i = 0; i < ppapi_plugins_.size(); i++) { | 620 for (size_t i = 0; i < ppapi_plugins_.size(); i++) { |
| 619 if (ppapi_plugins_[i].path == plugin_path) { | 621 if (ppapi_plugins_[i].path == plugin_path) { |
| 620 info = &ppapi_plugins_[i]; | 622 info = &ppapi_plugins_[i]; |
| 621 break; | 623 break; |
| 622 } | 624 } |
| 623 } | 625 } |
| 624 if (info) | 626 if (info) |
| 625 return info; | 627 return info; |
| 626 // We did not find the plugin in our list. But wait! the plugin can also | 628 // We did not find the plugin in our list. But wait! the plugin can also |
| 627 // be a latecomer, as it happens with pepper flash. This information | 629 // be a latecomer, as it happens with pepper flash. This information |
| 628 // can be obtained from the PluginList singleton and we can use it to | 630 // can be obtained from the PluginList singleton and we can use it to |
| 629 // construct it and add it to the list. This same deal needs to be done | 631 // construct it and add it to the list. This same deal needs to be done |
| 630 // in the renderer side in PepperPluginRegistry. | 632 // in the renderer side in PepperPluginRegistry. |
| 631 webkit::WebPluginInfo webplugin_info; | 633 webkit::WebPluginInfo webplugin_info; |
| 632 if (!GetPluginInfoByPath(plugin_path, &webplugin_info)) | 634 if (!GetPluginInfoByPath(plugin_path, &webplugin_info)) |
| 633 return NULL; | 635 return NULL; |
| 634 PepperPluginInfo new_pepper_info; | 636 PepperPluginInfo new_pepper_info; |
| 635 if (!MakePepperPluginInfo(webplugin_info, &new_pepper_info)) | 637 if (!MakePepperPluginInfo(webplugin_info, &new_pepper_info)) |
| 636 return NULL; | 638 return NULL; |
| 637 ppapi_plugins_.push_back(new_pepper_info); | 639 ppapi_plugins_.push_back(new_pepper_info); |
| 638 return &ppapi_plugins_[ppapi_plugins_.size() - 1]; | 640 return &ppapi_plugins_[ppapi_plugins_.size() - 1]; |
| 639 } | 641 } |
| 640 | 642 |
| 641 #if defined(OS_POSIX) && !defined(OS_OPENBSD) && !defined(OS_ANDROID) | 643 #if defined(OS_POSIX) && !defined(OS_OPENBSD) && !defined(OS_ANDROID) |
| 642 // static | 644 // static |
| 643 void PluginServiceImpl::RegisterFilePathWatcher(FilePathWatcher* watcher, | 645 void PluginServiceImpl::RegisterFilePathWatcher(FilePathWatcher* watcher, |
| 644 const FilePath& path) { | 646 const base::FilePath& path) { |
| 645 bool result = watcher->Watch(path, false, | 647 bool result = watcher->Watch(path, false, |
| 646 base::Bind(&NotifyPluginDirChanged)); | 648 base::Bind(&NotifyPluginDirChanged)); |
| 647 DCHECK(result); | 649 DCHECK(result); |
| 648 } | 650 } |
| 649 #endif | 651 #endif |
| 650 | 652 |
| 651 void PluginServiceImpl::SetFilter(PluginServiceFilter* filter) { | 653 void PluginServiceImpl::SetFilter(PluginServiceFilter* filter) { |
| 652 filter_ = filter; | 654 filter_ = filter; |
| 653 } | 655 } |
| 654 | 656 |
| 655 PluginServiceFilter* PluginServiceImpl::GetFilter() { | 657 PluginServiceFilter* PluginServiceImpl::GetFilter() { |
| 656 return filter_; | 658 return filter_; |
| 657 } | 659 } |
| 658 | 660 |
| 659 void PluginServiceImpl::ForcePluginShutdown(const FilePath& plugin_path) { | 661 void PluginServiceImpl::ForcePluginShutdown(const base::FilePath& plugin_path) { |
| 660 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 662 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
| 661 BrowserThread::PostTask( | 663 BrowserThread::PostTask( |
| 662 BrowserThread::IO, FROM_HERE, | 664 BrowserThread::IO, FROM_HERE, |
| 663 base::Bind(&PluginServiceImpl::ForcePluginShutdown, | 665 base::Bind(&PluginServiceImpl::ForcePluginShutdown, |
| 664 base::Unretained(this), plugin_path)); | 666 base::Unretained(this), plugin_path)); |
| 665 return; | 667 return; |
| 666 } | 668 } |
| 667 | 669 |
| 668 PluginProcessHost* plugin = FindNpapiPluginProcess(plugin_path); | 670 PluginProcessHost* plugin = FindNpapiPluginProcess(plugin_path); |
| 669 if (plugin) | 671 if (plugin) |
| 670 plugin->ForceShutdown(); | 672 plugin->ForceShutdown(); |
| 671 } | 673 } |
| 672 | 674 |
| 673 static const unsigned int kMaxCrashesPerInterval = 3; | 675 static const unsigned int kMaxCrashesPerInterval = 3; |
| 674 static const unsigned int kCrashesInterval = 120; | 676 static const unsigned int kCrashesInterval = 120; |
| 675 | 677 |
| 676 void PluginServiceImpl::RegisterPluginCrash(const FilePath& path) { | 678 void PluginServiceImpl::RegisterPluginCrash(const base::FilePath& path) { |
| 677 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 679 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 678 std::map<FilePath, std::vector<base::Time> >::iterator i = | 680 std::map<base::FilePath, std::vector<base::Time> >::iterator i = |
| 679 crash_times_.find(path); | 681 crash_times_.find(path); |
| 680 if (i == crash_times_.end()) { | 682 if (i == crash_times_.end()) { |
| 681 crash_times_[path] = std::vector<base::Time>(); | 683 crash_times_[path] = std::vector<base::Time>(); |
| 682 i = crash_times_.find(path); | 684 i = crash_times_.find(path); |
| 683 } | 685 } |
| 684 if (i->second.size() == kMaxCrashesPerInterval) { | 686 if (i->second.size() == kMaxCrashesPerInterval) { |
| 685 i->second.erase(i->second.begin()); | 687 i->second.erase(i->second.begin()); |
| 686 } | 688 } |
| 687 base::Time time = base::Time::Now(); | 689 base::Time time = base::Time::Now(); |
| 688 i->second.push_back(time); | 690 i->second.push_back(time); |
| 689 } | 691 } |
| 690 | 692 |
| 691 bool PluginServiceImpl::IsPluginUnstable(const FilePath& path) { | 693 bool PluginServiceImpl::IsPluginUnstable(const base::FilePath& path) { |
| 692 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 694 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 693 std::map<FilePath, std::vector<base::Time> >::const_iterator i = | 695 std::map<base::FilePath, std::vector<base::Time> >::const_iterator i = |
| 694 crash_times_.find(path); | 696 crash_times_.find(path); |
| 695 if (i == crash_times_.end()) { | 697 if (i == crash_times_.end()) { |
| 696 return false; | 698 return false; |
| 697 } | 699 } |
| 698 if (i->second.size() != kMaxCrashesPerInterval) { | 700 if (i->second.size() != kMaxCrashesPerInterval) { |
| 699 return false; | 701 return false; |
| 700 } | 702 } |
| 701 base::TimeDelta delta = base::Time::Now() - i->second[0]; | 703 base::TimeDelta delta = base::Time::Now() - i->second[0]; |
| 702 if (delta.InSeconds() <= kCrashesInterval) { | 704 if (delta.InSeconds() <= kCrashesInterval) { |
| 703 return true; | 705 return true; |
| 704 } | 706 } |
| 705 return false; | 707 return false; |
| 706 } | 708 } |
| 707 | 709 |
| 708 void PluginServiceImpl::RefreshPlugins() { | 710 void PluginServiceImpl::RefreshPlugins() { |
| 709 plugin_list_->RefreshPlugins(); | 711 plugin_list_->RefreshPlugins(); |
| 710 } | 712 } |
| 711 | 713 |
| 712 void PluginServiceImpl::AddExtraPluginPath(const FilePath& path) { | 714 void PluginServiceImpl::AddExtraPluginPath(const base::FilePath& path) { |
| 713 plugin_list_->AddExtraPluginPath(path); | 715 plugin_list_->AddExtraPluginPath(path); |
| 714 } | 716 } |
| 715 | 717 |
| 716 void PluginServiceImpl::AddExtraPluginDir(const FilePath& path) { | 718 void PluginServiceImpl::AddExtraPluginDir(const base::FilePath& path) { |
| 717 plugin_list_->AddExtraPluginDir(path); | 719 plugin_list_->AddExtraPluginDir(path); |
| 718 } | 720 } |
| 719 | 721 |
| 720 void PluginServiceImpl::RemoveExtraPluginPath(const FilePath& path) { | 722 void PluginServiceImpl::RemoveExtraPluginPath(const base::FilePath& path) { |
| 721 plugin_list_->RemoveExtraPluginPath(path); | 723 plugin_list_->RemoveExtraPluginPath(path); |
| 722 } | 724 } |
| 723 | 725 |
| 724 void PluginServiceImpl::UnregisterInternalPlugin(const FilePath& path) { | 726 void PluginServiceImpl::UnregisterInternalPlugin(const base::FilePath& path) { |
| 725 plugin_list_->UnregisterInternalPlugin(path); | 727 plugin_list_->UnregisterInternalPlugin(path); |
| 726 } | 728 } |
| 727 | 729 |
| 728 void PluginServiceImpl::SetPluginListForTesting( | 730 void PluginServiceImpl::SetPluginListForTesting( |
| 729 webkit::npapi::PluginList* plugin_list) { | 731 webkit::npapi::PluginList* plugin_list) { |
| 730 plugin_list_ = plugin_list; | 732 plugin_list_ = plugin_list; |
| 731 } | 733 } |
| 732 | 734 |
| 733 #if defined(OS_MACOSX) | 735 #if defined(OS_MACOSX) |
| 734 void PluginServiceImpl::AppActivated() { | 736 void PluginServiceImpl::AppActivated() { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 746 void PluginServiceImpl::GetInternalPlugins( | 748 void PluginServiceImpl::GetInternalPlugins( |
| 747 std::vector<webkit::WebPluginInfo>* plugins) { | 749 std::vector<webkit::WebPluginInfo>* plugins) { |
| 748 plugin_list_->GetInternalPlugins(plugins); | 750 plugin_list_->GetInternalPlugins(plugins); |
| 749 } | 751 } |
| 750 | 752 |
| 751 webkit::npapi::PluginList* PluginServiceImpl::GetPluginList() { | 753 webkit::npapi::PluginList* PluginServiceImpl::GetPluginList() { |
| 752 return plugin_list_; | 754 return plugin_list_; |
| 753 } | 755 } |
| 754 | 756 |
| 755 } // namespace content | 757 } // namespace content |
| OLD | NEW |