bool CefPluginServiceFilter::IsPluginAvailable()

in libcef/browser/plugins/plugin_service_filter.cc [60:163]


bool CefPluginServiceFilter::IsPluginAvailable(
    int render_process_id,
    int render_frame_id,
    const GURL& url,
    bool is_main_frame,
    const url::Origin& main_frame_origin,
    content::WebPluginInfo* plugin,
    chrome::mojom::PluginStatus* status) {
  CEF_REQUIRE_UIT();
  DCHECK_GT(render_process_id, 0);

  if (*status == chrome::mojom::PluginStatus::kNotFound) {
    // The plugin does not exist so no need to query the handler.
    return false;
  }

  if (plugin->path == CefString(AlloyContentClient::kPDFPluginPath)) {
    // Always allow the internal PDF plugin to load.
    *status = chrome::mojom::PluginStatus::kAllowed;
    return true;
  }

  const GURL& policy_url = main_frame_origin.GetURL();
  if (!policy_url.is_empty() &&
      policy_url.scheme() == extensions::kExtensionScheme) {
    // Always allow extension origins to load plugins.
    // TODO(extensions): Revisit this decision once CEF supports more than just
    // the PDF extension.
    *status = chrome::mojom::PluginStatus::kAllowed;
    return true;
  }

  const auto global_id = frame_util::MakeGlobalId(
      render_process_id, render_frame_id, /*allow_invalid_frame_id=*/true);
  auto browser_context = CefBrowserContext::FromGlobalId(global_id, false);
  CefRefPtr<CefRequestContextHandler> handler;
  if (browser_context) {
    handler = browser_context->GetHandler(global_id, false);
  }

  if (!handler) {
    // No handler so go with the default plugin load decision.
    return *status != chrome::mojom::PluginStatus::kDisabled;
  }

  // Check for a cached plugin load decision.
  if (browser_context->HasPluginLoadDecision(render_process_id, plugin->path,
                                             is_main_frame, main_frame_origin,
                                             status)) {
    return *status != chrome::mojom::PluginStatus::kDisabled;
  }

  CefRefPtr<CefWebPluginInfoImpl> pluginInfo(new CefWebPluginInfoImpl(*plugin));

  cef_plugin_policy_t plugin_policy = PLUGIN_POLICY_ALLOW;
  switch (*status) {
    case chrome::mojom::PluginStatus::kAllowed:
      plugin_policy = PLUGIN_POLICY_ALLOW;
      break;
    case chrome::mojom::PluginStatus::kBlocked:
    case chrome::mojom::PluginStatus::kBlockedByPolicy:
    case chrome::mojom::PluginStatus::kOutdatedBlocked:
    case chrome::mojom::PluginStatus::kOutdatedDisallowed:
    case chrome::mojom::PluginStatus::kUnauthorized:
      plugin_policy = PLUGIN_POLICY_BLOCK;
      break;
    case chrome::mojom::PluginStatus::kDisabled:
      plugin_policy = PLUGIN_POLICY_DISABLE;
      break;
    case chrome::mojom::PluginStatus::kPlayImportantContent:
      plugin_policy = PLUGIN_POLICY_DETECT_IMPORTANT;
      break;
    default:
      NOTREACHED();
      break;
  }

  if (handler->OnBeforePluginLoad(plugin->mime_types[0].mime_type,
                                  url.possibly_invalid_spec(), is_main_frame,
                                  policy_url.possibly_invalid_spec(),
                                  pluginInfo.get(), &plugin_policy)) {
    switch (plugin_policy) {
      case PLUGIN_POLICY_ALLOW:
        *status = chrome::mojom::PluginStatus::kAllowed;
        break;
      case PLUGIN_POLICY_DETECT_IMPORTANT:
        *status = chrome::mojom::PluginStatus::kPlayImportantContent;
        break;
      case PLUGIN_POLICY_BLOCK:
        *status = chrome::mojom::PluginStatus::kBlocked;
        break;
      case PLUGIN_POLICY_DISABLE:
        *status = chrome::mojom::PluginStatus::kDisabled;
        break;
    }
  }

  // Cache the plugin load decision.
  browser_context->AddPluginLoadDecision(render_process_id, plugin->path,
                                         is_main_frame, main_frame_origin,
                                         *status);

  return *status != chrome::mojom::PluginStatus::kDisabled;
}