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

Side by Side Diff: webkit/plugins/npapi/plugin_list.cc

Issue 5699005: Policy: Re-enabled plugin still disabled (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Made *_to_disable_ sets and extracted some functionality from LoadPlugins for better testability. Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "webkit/plugins/npapi/plugin_list.h" 5 #include "webkit/plugins/npapi/plugin_list.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/stl_util-inl.h"
13 #include "base/string_split.h" 12 #include "base/string_split.h"
14 #include "base/string_util.h" 13 #include "base/string_util.h"
15 #include "base/sys_string_conversions.h" 14 #include "base/sys_string_conversions.h"
16 #include "base/utf_string_conversions.h" 15 #include "base/utf_string_conversions.h"
17 #include "googleurl/src/gurl.h" 16 #include "googleurl/src/gurl.h"
18 #include "net/base/mime_util.h" 17 #include "net/base/mime_util.h"
19 #include "webkit/glue/webkit_glue.h" 18 #include "webkit/glue/webkit_glue.h"
20 #include "webkit/plugins/npapi/plugin_constants_win.h" 19 #include "webkit/plugins/npapi/plugin_constants_win.h"
21 #include "webkit/plugins/npapi/plugin_lib.h" 20 #include "webkit/plugins/npapi/plugin_lib.h"
22 #include "webkit/plugins/plugin_switches.h" 21 #include "webkit/plugins/plugin_switches.h"
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 void PluginList::RegisterInternalPlugin(const FilePath& filename, 226 void PluginList::RegisterInternalPlugin(const FilePath& filename,
228 const std::string& name, 227 const std::string& name,
229 const std::string& description, 228 const std::string& description,
230 const std::string& mime_type_str, 229 const std::string& mime_type_str,
231 const PluginEntryPoints& entry_points) { 230 const PluginEntryPoints& entry_points) {
232 InternalPlugin plugin; 231 InternalPlugin plugin;
233 plugin.info.path = filename; 232 plugin.info.path = filename;
234 plugin.info.name = ASCIIToUTF16(name); 233 plugin.info.name = ASCIIToUTF16(name);
235 plugin.info.version = ASCIIToUTF16("1"); 234 plugin.info.version = ASCIIToUTF16("1");
236 plugin.info.desc = ASCIIToUTF16(description); 235 plugin.info.desc = ASCIIToUTF16(description);
237 plugin.info.enabled = true; 236 plugin.info.enabled = WebPluginInfo::USER_ENABLED_POLICY_UNMANAGED;
238 237
239 WebPluginMimeType mime_type; 238 WebPluginMimeType mime_type;
240 mime_type.mime_type = mime_type_str; 239 mime_type.mime_type = mime_type_str;
241 plugin.info.mime_types.push_back(mime_type); 240 plugin.info.mime_types.push_back(mime_type);
242 241
243 plugin.entry_points = entry_points; 242 plugin.entry_points = entry_points;
244 243
245 base::AutoLock lock(lock_); 244 base::AutoLock lock(lock_);
246 internal_plugins_.push_back(plugin); 245 internal_plugins_.push_back(plugin);
247 } 246 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 316
318 parsed_mime_types->push_back(mime_type); 317 parsed_mime_types->push_back(mime_type);
319 } 318 }
320 319
321 return true; 320 return true;
322 } 321 }
323 322
324 PluginList::PluginList() 323 PluginList::PluginList()
325 : plugins_loaded_(false), 324 : plugins_loaded_(false),
326 plugins_need_refresh_(false), 325 plugins_need_refresh_(false),
327 disable_outdated_plugins_(false), 326 disable_outdated_plugins_(false) {
328 next_priority_(0) {
329 PlatformInit(); 327 PlatformInit();
330 AddHardcodedPluginGroups(); 328 AddHardcodedPluginGroups();
331 } 329 }
332 330
333 bool PluginList::ShouldDisableGroup(const string16& group_name) {
334 base::AutoLock lock(lock_);
335 if (PluginGroup::IsPluginNameDisabledByPolicy(group_name)) {
336 disabled_groups_.insert(group_name);
337 return true;
338 }
339 return disabled_groups_.count(group_name) > 0;
340 }
341
342 void PluginList::LoadPlugins(bool refresh) { 331 void PluginList::LoadPlugins(bool refresh) {
343 // Don't want to hold the lock while loading new plugins, so we don't block 332 // Don't want to hold the lock while loading new plugins, so we don't block
344 // other methods if they're called on other threads. 333 // other methods if they're called on other threads.
345 std::vector<FilePath> extra_plugin_paths; 334 std::vector<FilePath> extra_plugin_paths;
346 std::vector<FilePath> extra_plugin_dirs; 335 std::vector<FilePath> extra_plugin_dirs;
347 std::vector<InternalPlugin> internal_plugins; 336 std::vector<InternalPlugin> internal_plugins;
348 { 337 {
349 base::AutoLock lock(lock_); 338 base::AutoLock lock(lock_);
350 if (plugins_loaded_ && !refresh && !plugins_need_refresh_) 339 if (plugins_loaded_ && !refresh && !plugins_need_refresh_)
351 return; 340 return;
352 341
353 // Clear the refresh bit now, because it might get set again before we 342 // Clear the refresh bit now, because it might get set again before we
354 // reach the end of the method. 343 // reach the end of the method.
355 plugins_need_refresh_ = false; 344 plugins_need_refresh_ = false;
356 extra_plugin_paths = extra_plugin_paths_; 345 extra_plugin_paths = extra_plugin_paths_;
357 extra_plugin_dirs = extra_plugin_dirs_; 346 extra_plugin_dirs = extra_plugin_dirs_;
358 internal_plugins = internal_plugins_; 347 internal_plugins = internal_plugins_;
359 } 348 }
360 349
361 std::vector<WebPluginInfo> new_plugins; 350 ScopedVector<PluginGroup> new_plugin_groups;
362 std::set<FilePath> visited_plugins; 351 std::set<FilePath> visited_plugins;
363 352
364 std::vector<FilePath> directories_to_scan; 353 std::vector<FilePath> directories_to_scan;
365 GetPluginDirectories(&directories_to_scan); 354 GetPluginDirectories(&directories_to_scan);
366 355
367 // Load internal plugins first so that, if both an internal plugin and a 356 // Load internal plugins first so that, if both an internal plugin and a
368 // "discovered" plugin want to handle the same type, the internal plugin 357 // "discovered" plugin want to handle the same type, the internal plugin
369 // will have precedence. 358 // will have precedence.
370 for (size_t i = 0; i < internal_plugins.size(); ++i) { 359 for (size_t i = 0; i < internal_plugins.size(); ++i) {
371 if (internal_plugins[i].info.path.value() == kDefaultPluginLibraryName) 360 if (internal_plugins[i].info.path.value() == kDefaultPluginLibraryName)
372 continue; 361 continue;
373 LoadPlugin(internal_plugins[i].info.path, &new_plugins); 362 LoadPlugin(internal_plugins[i].info.path, &new_plugin_groups);
374 } 363 }
375 364
376 for (size_t i = 0; i < extra_plugin_paths.size(); ++i) { 365 for (size_t i = 0; i < extra_plugin_paths.size(); ++i) {
377 const FilePath& path = extra_plugin_paths[i]; 366 const FilePath& path = extra_plugin_paths[i];
378 if (visited_plugins.find(path) != visited_plugins.end()) 367 if (visited_plugins.find(path) != visited_plugins.end())
379 continue; 368 continue;
380 LoadPlugin(path, &new_plugins); 369 LoadPlugin(path, &new_plugin_groups);
381 visited_plugins.insert(path); 370 visited_plugins.insert(path);
382 } 371 }
383 372
384 for (size_t i = 0; i < extra_plugin_dirs.size(); ++i) { 373 for (size_t i = 0; i < extra_plugin_dirs.size(); ++i) {
385 LoadPluginsFromDir(extra_plugin_dirs[i], &new_plugins, &visited_plugins); 374 LoadPluginsFromDir(
375 extra_plugin_dirs[i], &new_plugin_groups, &visited_plugins);
386 } 376 }
387 377
388 for (size_t i = 0; i < directories_to_scan.size(); ++i) { 378 for (size_t i = 0; i < directories_to_scan.size(); ++i) {
389 LoadPluginsFromDir(directories_to_scan[i], &new_plugins, &visited_plugins); 379 LoadPluginsFromDir(
380 directories_to_scan[i], &new_plugin_groups, &visited_plugins);
390 } 381 }
391 382
392 #if defined(OS_WIN) 383 #if defined(OS_WIN)
393 LoadPluginsFromRegistry(&new_plugins, &visited_plugins); 384 LoadPluginsFromRegistry(&new_plugin_groups, &visited_plugins);
394 #endif 385 #endif
395 386
396 // Load the default plugin last. 387 // Load the default plugin last.
397 if (webkit_glue::IsDefaultPluginEnabled()) 388 if (webkit_glue::IsDefaultPluginEnabled())
398 LoadPlugin(FilePath(kDefaultPluginLibraryName), &new_plugins); 389 LoadPlugin(FilePath(kDefaultPluginLibraryName), &new_plugin_groups);
399 390
400 // Disable all of the plugins and plugin groups that are disabled by policy. 391 base::AutoLock lock(lock_);
401 // There's currenly a bug that makes it impossible to correctly re-enable 392 // Update the enabled status of the newly loaded plugins.
402 // plugins or plugin-groups to their original, "pre-policy" state, so 393 UpdatePluginsEnabledFlags(&new_plugin_groups);
403 // plugins and groups are only changed to a more "safe" state after a policy
404 // change, i.e. from enabled to disabled. See bug 54681.
405 for (PluginGroup::PluginMap::iterator it = plugin_groups_.begin();
406 it != plugin_groups_.end(); ++it) {
407 PluginGroup* group = it->second;
408 string16 group_name = group->GetGroupName();
409 if (ShouldDisableGroup(group_name)) {
410 group->Enable(false);
411 }
412 394
413 if (disable_outdated_plugins_) { 395 plugin_groups_.swap(new_plugin_groups);
414 group->DisableOutdatedPlugins();
415 }
416 if (!group->Enabled()) {
417 base::AutoLock lock(lock_);
418 disabled_groups_.insert(group_name);
419 }
420 }
421
422 // Only update the data now since loading plugins can take a while.
423 base::AutoLock lock(lock_);
424
425 plugins_ = new_plugins;
426 plugins_loaded_ = true; 396 plugins_loaded_ = true;
427 } 397 }
428 398
399 void PluginList::UpdatePluginsEnabledFlags(
400 ScopedVector<PluginGroup>* plugin_groups) {
401 // Grab all plugins that were found before to copy enabled statuses.
402 std::vector<WebPluginInfo> old_plugins;
403 for (size_t i = 0; i < plugin_groups_.size(); ++i) {
404 const std::vector<WebPluginInfo>& gr_plugins =
405 plugin_groups_[i]->web_plugins_info();
406 old_plugins.insert(old_plugins.end(), gr_plugins.begin(), gr_plugins.end());
407 }
408 // Disable all of the plugins and plugin groups that are disabled by policy.
409 for (size_t i = 0; i < plugin_groups->size(); ++i) {
410 PluginGroup* group = (*plugin_groups)[i];
411 string16 group_name = group->GetGroupName();
412
413 std::vector<WebPluginInfo>& gr_plugins = group->GetPluginsContainer();
414 for (size_t j = 0; j < gr_plugins.size(); ++j) {
415 int plugin_found = -1;
416 for (size_t k = 0; k < old_plugins.size(); ++k) {
417 if (gr_plugins[j].path == old_plugins[k].path) {
418 plugin_found = k;
419 break;
420 }
421 }
422 if (plugin_found >= 0)
423 gr_plugins[j].enabled = old_plugins[plugin_found].enabled;
424 // Set the disabled flag of all plugins scheduled for disabling.
425 if (plugins_to_disable_.find(gr_plugins[j].path) !=
426 plugins_to_disable_.end()) {
427 group->DisablePlugin(gr_plugins[j].path);
428 }
429 }
430 if (group->IsEmpty()) {
431 if (!group->Enabled())
432 groups_to_disable_.insert(group->GetGroupName());
433 plugin_groups->erase(plugin_groups->begin() + i);
434 --i;
435 continue;
436 }
437
438 group->EnforceGroupPolicy();
439 if (disable_outdated_plugins_)
440 group->DisableOutdatedPlugins();
441 }
442 // We flush the list of prematurely disabled plugins after the load has
443 // finished. If for some reason a plugin reappears on a second load it is
444 // going to be loaded normally. This is only true for non-policy controlled
445 // plugins though.
446 plugins_to_disable_.clear();
447 }
448
429 void PluginList::LoadPlugin(const FilePath& path, 449 void PluginList::LoadPlugin(const FilePath& path,
430 std::vector<WebPluginInfo>* plugins) { 450 ScopedVector<PluginGroup>* plugin_groups) {
431 LOG_IF(ERROR, PluginList::DebugPluginLoading()) 451 LOG_IF(ERROR, PluginList::DebugPluginLoading())
432 << "Loading plugin " << path.value(); 452 << "Loading plugin " << path.value();
433
434 WebPluginInfo plugin_info; 453 WebPluginInfo plugin_info;
435 const PluginEntryPoints* entry_points; 454 const PluginEntryPoints* entry_points;
436 455
437 if (!ReadPluginInfo(path, &plugin_info, &entry_points)) 456 if (!ReadPluginInfo(path, &plugin_info, &entry_points))
438 return; 457 return;
439 458
440 if (!ShouldLoadPlugin(plugin_info, plugins)) 459 if (!ShouldLoadPlugin(plugin_info, plugin_groups))
441 return; 460 return;
442 461
443 if (path.value() != kDefaultPluginLibraryName 462 if (path.value() != kDefaultPluginLibraryName
444 #if defined(OS_WIN) && !defined(NDEBUG) 463 #if defined(OS_WIN) && !defined(NDEBUG)
445 && path.BaseName().value() != L"npspy.dll" // Make an exception for NPSPY 464 && path.BaseName().value() != L"npspy.dll" // Make an exception for NPSPY
446 #endif 465 #endif
447 ) { 466 ) {
448 for (size_t i = 0; i < plugin_info.mime_types.size(); ++i) { 467 for (size_t i = 0; i < plugin_info.mime_types.size(); ++i) {
449 // TODO: don't load global handlers for now. 468 // TODO: don't load global handlers for now.
450 // WebKit hands to the Plugin before it tries 469 // WebKit hands to the Plugin before it tries
451 // to handle mimeTypes on its own. 470 // to handle mimeTypes on its own.
452 const std::string &mime_type = plugin_info.mime_types[i].mime_type; 471 const std::string &mime_type = plugin_info.mime_types[i].mime_type;
453 if (mime_type == "*" ) 472 if (mime_type == "*" )
454 return; 473 return;
455 } 474 }
456 } 475 }
457 476
458 // Mark disabled plugins as such. (This has to happen before calling 477 AddToPluginGroups(plugin_info, plugin_groups);
459 // |AddToPluginGroups(plugin_info)|.)
460 if (disabled_plugins_.count(plugin_info.path)) {
461 plugin_info.enabled = false;
462 } else {
463 plugin_info.enabled = true;
464 }
465
466 base::AutoLock lock(lock_);
467 plugins->push_back(plugin_info);
468 AddToPluginGroups(plugin_info);
469 } 478 }
470 479
471 bool PluginList::SupportsType(const WebPluginInfo& info,
472 const std::string &mime_type,
473 bool allow_wildcard) {
474 // Webkit will ask for a plugin to handle empty mime types.
475 if (mime_type.empty())
476 return false;
477
478 for (size_t i = 0; i < info.mime_types.size(); ++i) {
479 const WebPluginMimeType& mime_info = info.mime_types[i];
480 if (net::MatchesMimeType(mime_info.mime_type, mime_type)) {
481 if (!allow_wildcard && mime_info.mime_type == "*") {
482 continue;
483 }
484 return true;
485 }
486 }
487 return false;
488 }
489
490 bool PluginList::SupportsExtension(const WebPluginInfo& info,
491 const std::string &extension,
492 std::string* actual_mime_type) {
493 for (size_t i = 0; i < info.mime_types.size(); ++i) {
494 const WebPluginMimeType& mime_type = info.mime_types[i];
495 for (size_t j = 0; j < mime_type.file_extensions.size(); ++j) {
496 if (mime_type.file_extensions[j] == extension) {
497 if (actual_mime_type)
498 *actual_mime_type = mime_type.mime_type;
499 return true;
500 }
501 }
502 }
503
504 return false;
505 }
506
507
508 void PluginList::GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) { 480 void PluginList::GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) {
509 LoadPlugins(refresh); 481 LoadPlugins(refresh);
510 482
511 base::AutoLock lock(lock_); 483 base::AutoLock lock(lock_);
512 *plugins = plugins_; 484 for (size_t i = 0; i < plugin_groups_.size(); ++i) {
485 const std::vector<WebPluginInfo>& gr_plugins =
486 plugin_groups_[i]->web_plugins_info();
487 plugins->insert(plugins->end(), gr_plugins.begin(), gr_plugins.end());
488 }
513 } 489 }
514 490
515 void PluginList::GetEnabledPlugins(bool refresh, 491 void PluginList::GetEnabledPlugins(bool refresh,
516 std::vector<WebPluginInfo>* plugins) { 492 std::vector<WebPluginInfo>* plugins) {
517 LoadPlugins(refresh); 493 LoadPlugins(refresh);
518 494
519 plugins->clear(); 495 plugins->clear();
520 base::AutoLock lock(lock_); 496 base::AutoLock lock(lock_);
521 for (std::vector<WebPluginInfo>::const_iterator it = plugins_.begin(); 497 for (size_t i = 0; i < plugin_groups_.size(); ++i) {
522 it != plugins_.end(); 498 const std::vector<WebPluginInfo>& gr_plugins =
523 ++it) { 499 plugin_groups_[i]->web_plugins_info();
524 if (it->enabled) 500 for (size_t i = 0; i < gr_plugins.size(); ++i) {
525 plugins->push_back(*it); 501 if (IsPluginEnabled(gr_plugins[i]))
502 plugins->push_back(gr_plugins[i]);
503 }
526 } 504 }
527 } 505 }
528 506
529 void PluginList::GetPluginInfoArray( 507 void PluginList::GetPluginInfoArray(
530 const GURL& url, 508 const GURL& url,
531 const std::string& mime_type, 509 const std::string& mime_type,
532 bool allow_wildcard, 510 bool allow_wildcard,
533 std::vector<WebPluginInfo>* info, 511 std::vector<WebPluginInfo>* info,
534 std::vector<std::string>* actual_mime_types) { 512 std::vector<std::string>* actual_mime_types) {
535 DCHECK(mime_type == StringToLowerASCII(mime_type)); 513 DCHECK(mime_type == StringToLowerASCII(mime_type));
536 DCHECK(info); 514 DCHECK(info);
537 515
538 LoadPlugins(false); 516 LoadPlugins(false);
539 base::AutoLock lock(lock_); 517 base::AutoLock lock(lock_);
540 info->clear(); 518 info->clear();
541 if (actual_mime_types) 519 if (actual_mime_types)
542 actual_mime_types->clear(); 520 actual_mime_types->clear();
543 521
544 std::set<FilePath> visited_plugins; 522 std::set<FilePath> visited_plugins;
545 523
546 // Add in enabled plugins by mime type. 524 // Add in enabled plugins by mime type.
547 WebPluginInfo default_plugin; 525 WebPluginInfo default_plugin;
548 for (size_t i = 0; i < plugins_.size(); ++i) { 526 for (size_t i = 0; i < plugin_groups_.size(); ++i) {
549 if (plugins_[i].enabled && 527 const std::vector<WebPluginInfo>& plugins =
550 SupportsType(plugins_[i], mime_type, allow_wildcard)) { 528 plugin_groups_[i]->web_plugins_info();
551 FilePath path = plugins_[i].path; 529 for (size_t i = 0; i < plugins.size(); ++i) {
552 if (path.value() != kDefaultPluginLibraryName && 530 if (IsPluginEnabled(plugins[i]) && SupportsType(plugins[i],
553 visited_plugins.insert(path).second) { 531 mime_type, allow_wildcard)) {
554 info->push_back(plugins_[i]); 532 FilePath path = plugins[i].path;
555 if (actual_mime_types) 533 if (path.value() != kDefaultPluginLibraryName &&
556 actual_mime_types->push_back(mime_type); 534 visited_plugins.insert(path).second) {
535 info->push_back(plugins[i]);
536 if (actual_mime_types)
537 actual_mime_types->push_back(mime_type);
538 }
557 } 539 }
558 } 540 }
559 } 541 }
560 542
561 // Add in enabled plugins by url. 543 // Add in enabled plugins by url.
562 std::string path = url.path(); 544 std::string path = url.path();
563 std::string::size_type last_dot = path.rfind('.'); 545 std::string::size_type last_dot = path.rfind('.');
564 if (last_dot != std::string::npos) { 546 if (last_dot != std::string::npos) {
565 std::string extension = StringToLowerASCII(std::string(path, last_dot+1)); 547 std::string extension = StringToLowerASCII(std::string(path, last_dot+1));
566 std::string actual_mime_type; 548 std::string actual_mime_type;
567 for (size_t i = 0; i < plugins_.size(); ++i) { 549 for (size_t i = 0; i < plugin_groups_.size(); ++i) {
568 if (plugins_[i].enabled && 550 const std::vector<WebPluginInfo>& plugins =
569 SupportsExtension(plugins_[i], extension, &actual_mime_type)) { 551 plugin_groups_[i]->web_plugins_info();
570 FilePath path = plugins_[i].path; 552 for (size_t i = 0; i < plugins.size(); ++i) {
571 if (path.value() != kDefaultPluginLibraryName && 553 if (IsPluginEnabled(plugins[i]) &&
572 visited_plugins.insert(path).second) { 554 SupportsExtension(plugins[i], extension, &actual_mime_type)) {
573 info->push_back(plugins_[i]); 555 FilePath path = plugins[i].path;
574 if (actual_mime_types) 556 if (path.value() != kDefaultPluginLibraryName &&
575 actual_mime_types->push_back(actual_mime_type); 557 visited_plugins.insert(path).second) {
558 info->push_back(plugins[i]);
559 if (actual_mime_types)
560 actual_mime_types->push_back(actual_mime_type);
561 }
576 } 562 }
577 } 563 }
578 } 564 }
579 } 565 }
580 566
581 // Add in disabled plugins by mime type. 567 // Add in disabled plugins by mime type.
582 for (size_t i = 0; i < plugins_.size(); ++i) { 568 for (size_t i = 0; i < plugin_groups_.size(); ++i) {
583 if (!plugins_[i].enabled && 569 const std::vector<WebPluginInfo>& plugins =
584 SupportsType(plugins_[i], mime_type, allow_wildcard)) { 570 plugin_groups_[i]->web_plugins_info();
585 FilePath path = plugins_[i].path; 571 for (size_t i = 0; i < plugins.size(); ++i) {
586 if (path.value() != kDefaultPluginLibraryName && 572 if (!IsPluginEnabled(plugins[i]) &&
587 visited_plugins.insert(path).second) { 573 SupportsType(plugins[i], mime_type, allow_wildcard)) {
588 info->push_back(plugins_[i]); 574 FilePath path = plugins[i].path;
589 if (actual_mime_types) 575 if (path.value() != kDefaultPluginLibraryName &&
590 actual_mime_types->push_back(mime_type); 576 visited_plugins.insert(path).second) {
577 info->push_back(plugins[i]);
578 if (actual_mime_types)
579 actual_mime_types->push_back(mime_type);
580 }
591 } 581 }
592 } 582 }
593 } 583 }
594 584
595 // Add the default plugin at the end if it supports the mime type given, 585 // Add the default plugin at the end if it supports the mime type given,
596 // and the default plugin is enabled. 586 // and the default plugin is enabled.
597 if (!plugins_.empty() && webkit_glue::IsDefaultPluginEnabled()) { 587 for (size_t i = 0; i < plugin_groups_.size(); ++i) {
598 const WebPluginInfo& default_info = plugins_.back(); 588 #if defined(OS_WIN)
599 if (SupportsType(default_info, mime_type, allow_wildcard)) { 589 if (plugin_groups_[i]->identifier().compare(
600 info->push_back(default_info); 590 WideToUTF8(kDefaultPluginLibraryName)) == 0) {
601 if (actual_mime_types) 591 #else
602 actual_mime_types->push_back(mime_type); 592 if (plugin_groups_[i]->identifier().compare(
593 kDefaultPluginLibraryName) == 0) {
594 #endif
595 DCHECK_NE(0U, plugin_groups_[i]->web_plugins_info().size());
596 const WebPluginInfo& default_info =
597 plugin_groups_[i]->web_plugins_info()[0];
598 if (SupportsType(default_info, mime_type, allow_wildcard)) {
599 info->push_back(default_info);
600 if (actual_mime_types)
601 actual_mime_types->push_back(mime_type);
602 }
603 } 603 }
604 } 604 }
605 } 605 }
606 606
607 bool PluginList::GetPluginInfo(const GURL& url, 607 bool PluginList::GetPluginInfo(const GURL& url,
608 const std::string& mime_type, 608 const std::string& mime_type,
609 bool allow_wildcard, 609 bool allow_wildcard,
610 WebPluginInfo* info, 610 WebPluginInfo* info,
611 std::string* actual_mime_type) { 611 std::string* actual_mime_type) {
612 DCHECK(info); 612 DCHECK(info);
(...skipping 17 matching lines...) Expand all
630 return true; 630 return true;
631 } 631 }
632 } 632 }
633 return false; 633 return false;
634 } 634 }
635 635
636 bool PluginList::GetPluginInfoByPath(const FilePath& plugin_path, 636 bool PluginList::GetPluginInfoByPath(const FilePath& plugin_path,
637 WebPluginInfo* info) { 637 WebPluginInfo* info) {
638 LoadPlugins(false); 638 LoadPlugins(false);
639 base::AutoLock lock(lock_); 639 base::AutoLock lock(lock_);
640 for (size_t i = 0; i < plugins_.size(); ++i) { 640 for (size_t i = 0; i < plugin_groups_.size(); ++i) {
641 if (plugins_[i].path == plugin_path) { 641 const std::vector<WebPluginInfo>& plugins =
642 *info = plugins_[i]; 642 plugin_groups_[i]->web_plugins_info();
643 return true; 643 for (size_t i = 0; i < plugins.size(); ++i) {
644 if (plugins[i].path == plugin_path) {
645 *info = plugins[i];
646 return true;
647 }
644 } 648 }
645 } 649 }
646 650
647 return false; 651 return false;
648 } 652 }
649 653
650 void PluginList::GetPluginGroups( 654 void PluginList::GetPluginGroups(
651 bool load_if_necessary, 655 bool load_if_necessary,
652 std::vector<PluginGroup>* plugin_groups) { 656 std::vector<PluginGroup>* plugin_groups) {
653 if (load_if_necessary) 657 if (load_if_necessary)
654 LoadPlugins(false); 658 LoadPlugins(false);
659 base::AutoLock lock(lock_);
655 plugin_groups->clear(); 660 plugin_groups->clear();
656 for (PluginGroup::PluginMap::const_iterator it = plugin_groups_.begin(); 661 for (size_t i = 0; i < plugin_groups_.size(); ++i) {
657 it != plugin_groups_.end(); ++it) { 662 // In some unit tests we can get confronted with empty groups but in real
658 if (!it->second->IsEmpty()) 663 // world code this if should never be false here.
659 plugin_groups->push_back(*it->second); 664 if(!plugin_groups_[i]->IsEmpty())
665 plugin_groups->push_back(*plugin_groups_[i]);
660 } 666 }
661 } 667 }
662 668
663 const PluginGroup* PluginList::GetPluginGroup( 669 const PluginGroup* PluginList::GetPluginGroup(
664 const WebPluginInfo& web_plugin_info) { 670 const WebPluginInfo& web_plugin_info) {
665 base::AutoLock lock(lock_); 671 base::AutoLock lock(lock_);
666 return AddToPluginGroups(web_plugin_info); 672 return AddToPluginGroups(web_plugin_info, &plugin_groups_);
667 } 673 }
668 674
669 string16 PluginList::GetPluginGroupName(std::string identifier) { 675 string16 PluginList::GetPluginGroupName(const std::string& identifier) {
670 PluginGroup::PluginMap::iterator it = plugin_groups_.find(identifier); 676 for (size_t i = 0; i < plugin_groups_.size(); ++i) {
671 if (it == plugin_groups_.end()) { 677 if(plugin_groups_[i]->identifier() == identifier)
672 return string16(); 678 return plugin_groups_[i]->GetGroupName();
673 } 679 }
674 return it->second->GetGroupName(); 680 return string16();
675 } 681 }
676 682
677 std::string PluginList::GetPluginGroupIdentifier( 683 std::string PluginList::GetPluginGroupIdentifier(
678 const WebPluginInfo& web_plugin_info) { 684 const WebPluginInfo& web_plugin_info) {
679 base::AutoLock lock(lock_); 685 base::AutoLock lock(lock_);
680 PluginGroup* group = AddToPluginGroups(web_plugin_info); 686 PluginGroup* group = AddToPluginGroups(web_plugin_info, &plugin_groups_);
681 return group->identifier(); 687 return group->identifier();
682 } 688 }
683 689
684 void PluginList::AddHardcodedPluginGroups() { 690 void PluginList::AddHardcodedPluginGroups() {
685 base::AutoLock lock(lock_); 691 base::AutoLock lock(lock_);
686 const PluginGroupDefinition* definitions = GetPluginGroupDefinitions(); 692 const PluginGroupDefinition* definitions = GetPluginGroupDefinitions();
687 for (size_t i = 0; i < GetPluginGroupDefinitionsSize(); ++i) { 693 for (size_t i = 0; i < GetPluginGroupDefinitionsSize(); ++i) {
688 PluginGroup* definition_group = PluginGroup::FromPluginGroupDefinition( 694 PluginGroup* definition_group = PluginGroup::FromPluginGroupDefinition(
689 definitions[i]); 695 definitions[i]);
690 std::string identifier = definition_group->identifier(); 696 plugin_groups_.push_back(definition_group);
691 DCHECK(plugin_groups_.find(identifier) == plugin_groups_.end());
692 plugin_groups_.insert(std::make_pair(identifier, definition_group));
693 } 697 }
694 } 698 }
695 699
696 PluginGroup* PluginList::AddToPluginGroups( 700 PluginGroup* PluginList::AddToPluginGroups(
697 const WebPluginInfo& web_plugin_info) { 701 const WebPluginInfo& web_plugin_info,
702 ScopedVector<PluginGroup>* plugin_groups) {
698 PluginGroup* group = NULL; 703 PluginGroup* group = NULL;
699 for (PluginGroup::PluginMap::iterator it = plugin_groups_.begin(); 704 for (size_t i = 0; i < plugin_groups->size(); ++i) {
700 it != plugin_groups_.end(); ++it) { 705 if ((*plugin_groups)[i]->Match(web_plugin_info)) {
701 if (it->second->Match(web_plugin_info)) 706 group = (*plugin_groups)[i];
702 group = it->second; 707 break;
708 }
703 } 709 }
704 if (!group) { 710 if (!group) {
705 group = PluginGroup::FromWebPluginInfo(web_plugin_info); 711 group = PluginGroup::FromWebPluginInfo(web_plugin_info);
712 // If group is scheduled for disabling do that now and remove it from the
713 // list.
714 if (groups_to_disable_.find(group->GetGroupName()) !=
715 groups_to_disable_.end()) {
716 group->EnableGroup(false);
717 groups_to_disable_.erase(group->GetGroupName());
718 }
706 std::string identifier = group->identifier(); 719 std::string identifier = group->identifier();
707 // If the identifier is not unique, use the full path. This means that we 720 // If the identifier is not unique, use the full path. This means that we
708 // probably won't be able to search for this group by identifier, but at 721 // probably won't be able to search for this group by identifier, but at
709 // least it's going to be in the set of plugin groups, and if there 722 // least it's going to be in the set of plugin groups, and if there
710 // is already a plug-in with the same filename, it's probably going to 723 // is already a plug-in with the same filename, it's probably going to
711 // handle the same MIME types (and it has a higher priority), so this one 724 // handle the same MIME types (and it has a higher priority), so this one
712 // is not going to run anyway. 725 // is not going to run anyway.
713 if (plugin_groups_.find(identifier) != plugin_groups_.end()) 726 for (size_t i = 0; i < plugin_groups->size(); ++i) {
714 identifier = PluginGroup::GetLongIdentifier(web_plugin_info); 727 if ((*plugin_groups)[i]->identifier() == identifier) {
715 DCHECK(plugin_groups_.find(identifier) == plugin_groups_.end()); 728 group->set_identifier(PluginGroup::GetLongIdentifier(web_plugin_info));
716 plugin_groups_.insert(std::make_pair(identifier, group)); 729 break;
730 }
731 }
732 plugin_groups->push_back(group);
717 } 733 }
718 group->AddPlugin(web_plugin_info, next_priority_++); 734 group->AddPlugin(web_plugin_info);
719 return group; 735 return group;
720 } 736 }
721 737
722 bool PluginList::EnablePlugin(const FilePath& filename) { 738 bool PluginList::EnablePlugin(const FilePath& filename) {
723 base::AutoLock lock(lock_); 739 base::AutoLock lock(lock_);
724 740 for (size_t i = 0; i < plugin_groups_.size(); ++i) {
725 bool did_enable = false; 741 if (plugin_groups_[i]->ContainsPlugin(filename))
726 742 return plugin_groups_[i]->EnablePlugin(filename);
727 std::set<FilePath>::iterator entry = disabled_plugins_.find(filename);
728 if (entry == disabled_plugins_.end())
729 return did_enable; // Early exit if plugin not in disabled list.
730
731 disabled_plugins_.erase(entry); // Remove from disabled list.
732
733 // Set enabled flags if necessary.
734 for (std::vector<WebPluginInfo>::iterator it = plugins_.begin();
735 it != plugins_.end();
736 ++it) {
737 if (it->path == filename) {
738 DCHECK(!it->enabled); // Should have been disabled.
739 it->enabled = true;
740 did_enable = true;
741 }
742 } 743 }
743 744 // Non existing plugin is being enabled. Check if it has been disabled before
744 return did_enable; 745 // and remove it.
746 return (plugins_to_disable_.erase(filename) != 0);
745 } 747 }
746 748
747 bool PluginList::DisablePlugin(const FilePath& filename) { 749 bool PluginList::DisablePlugin(const FilePath& filename) {
748 base::AutoLock lock(lock_); 750 base::AutoLock lock(lock_);
751 for (size_t i = 0; i < plugin_groups_.size(); ++i) {
752 if (plugin_groups_[i]->ContainsPlugin(filename))
753 return plugin_groups_[i]->DisablePlugin(filename);
754 }
755 // Non existing plugin is being disabled. Queue the plugin so that on the next
756 // load plugins call they will be disabled.
757 // Check if we already have this one to avoid double inclusion.
758 plugins_to_disable_.insert(filename);
759 return true;
760 }
749 761
750 bool did_disable = false; 762 bool PluginList::EnableGroup(bool enable, const string16& group_name) {
751 763 base::AutoLock lock(lock_);
752 if (disabled_plugins_.find(filename) != disabled_plugins_.end()) 764 PluginGroup* group = NULL;
753 return did_disable; // Early exit if plugin already in disabled list. 765 for (size_t i = 0; i < plugin_groups_.size(); ++i) {
754 766 if (plugin_groups_[i]->GetGroupName().find(group_name) != string16::npos) {
755 disabled_plugins_.insert(filename); // Add to disabled list. 767 group = plugin_groups_[i];
756 768 break;
757 // Unset enabled flags if necessary. 769 }
758 for (std::vector<WebPluginInfo>::iterator it = plugins_.begin(); 770 }
759 it != plugins_.end(); 771 if (!group) {
760 ++it) { 772 // Non existing group is being enabled. Queue the group so that on the next
761 if (it->path == filename) { 773 // load plugins call they will be disabled.
762 DCHECK(it->enabled); // Should have been enabled. 774 if(!enable) {
763 it->enabled = false; 775 groups_to_disable_.insert(group_name);
764 did_disable = true; 776 return true;
777 } else {
778 return (groups_to_disable_.erase(group_name) != 0);
765 } 779 }
766 } 780 }
767 781
768 return did_disable; 782 return group->EnableGroup(enable);
769 } 783 }
770 784
771 bool PluginList::EnableGroup(bool enable, const string16& group_name) { 785 bool PluginList::SupportsType(const WebPluginInfo& plugin,
772 bool did_change = false; 786 const std::string& mime_type,
773 { 787 bool allow_wildcard) {
774 base::AutoLock lock(lock_); 788 // Webkit will ask for a plugin to handle empty mime types.
789 if (mime_type.empty())
790 return false;
775 791
776 std::set<string16>::iterator entry = disabled_groups_.find(group_name); 792 for (size_t i = 0; i < plugin.mime_types.size(); ++i) {
777 if (enable) { 793 const WebPluginMimeType& mime_info = plugin.mime_types[i];
778 if (entry == disabled_groups_.end()) 794 if (net::MatchesMimeType(mime_info.mime_type, mime_type)) {
779 return did_change; // Early exit if group not in disabled list. 795 if (!allow_wildcard && mime_info.mime_type == "*")
780 disabled_groups_.erase(entry); // Remove from disabled list. 796 continue;
781 } else { 797 return true;
782 if (entry != disabled_groups_.end())
783 return did_change; // Early exit if group already in disabled list.
784 disabled_groups_.insert(group_name);
785 } 798 }
786 } 799 }
800 return false;
801 }
787 802
788 for (PluginGroup::PluginMap::iterator it = plugin_groups_.begin(); 803 bool PluginList::SupportsExtension(const WebPluginInfo& plugin,
789 it != plugin_groups_.end(); ++it) { 804 const std::string& extension,
790 if (it->second->GetGroupName() == group_name) { 805 std::string* actual_mime_type) {
791 if (it->second->Enabled() != enable) { 806 for (size_t i = 0; i < plugin.mime_types.size(); ++i) {
792 it->second->Enable(enable); 807 const WebPluginMimeType& mime_type = plugin.mime_types[i];
793 did_change = true; 808 for (size_t j = 0; j < mime_type.file_extensions.size(); ++j) {
794 break; 809 if (mime_type.file_extensions[j] == extension) {
810 if (actual_mime_type)
811 *actual_mime_type = mime_type.mime_type;
812 return true;
795 } 813 }
796 } 814 }
797 } 815 }
798 816 return false;
799 return did_change;
800 } 817 }
801 818
802 void PluginList::DisableOutdatedPluginGroups() { 819 void PluginList::DisableOutdatedPluginGroups() {
803 disable_outdated_plugins_ = true; 820 disable_outdated_plugins_ = true;
804 } 821 }
805 822
806 PluginList::~PluginList() { 823 PluginList::~PluginList() {
807 Shutdown();
808 } 824 }
809 825
810 void PluginList::Shutdown() {
811 STLDeleteContainerPairSecondPointers(plugin_groups_.begin(),
812 plugin_groups_.end());
813 }
814 826
815 } // namespace npapi 827 } // namespace npapi
816 } // namespace webkit 828 } // namespace webkit
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698