|  | // Copyright 2012 The Chromium Authors | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "chrome/browser/plugins/plugin_observer.h" | 
|  |  | 
|  | #include <utility> | 
|  |  | 
|  | #include "base/functional/bind.h" | 
|  | #include "base/memory/raw_ptr.h" | 
|  | #include "build/build_config.h" | 
|  | #include "chrome/app/vector_icons/vector_icons.h" | 
|  | #include "chrome/browser/browser_process.h" | 
|  | #include "chrome/browser/infobars/simple_alert_infobar_creator.h" | 
|  | #include "chrome/browser/plugins/plugin_observer_common.h" | 
|  | #include "chrome/browser/plugins/reload_plugin_infobar_delegate.h" | 
|  | #include "chrome/common/buildflags.h" | 
|  | #include "chrome/grit/generated_resources.h" | 
|  | #include "components/download/public/common/download_url_parameters.h" | 
|  | #include "components/infobars/content/content_infobar_manager.h" | 
|  | #include "components/metrics_services_manager/metrics_services_manager.h" | 
|  | #include "content/public/browser/browser_context.h" | 
|  | #include "content/public/browser/download_manager.h" | 
|  | #include "content/public/browser/plugin_service.h" | 
|  | #include "content/public/browser/render_frame_host.h" | 
|  | #include "content/public/browser/render_process_host.h" | 
|  | #include "content/public/browser/render_view_host.h" | 
|  | #include "content/public/browser/web_contents.h" | 
|  | #include "content/public/browser/web_contents_delegate.h" | 
|  | #include "content/public/common/webplugininfo.h" | 
|  | #include "extensions/browser/guest_view/web_view/web_view_guest.h" | 
|  | #include "mojo/public/cpp/bindings/remote.h" | 
|  | #include "net/traffic_annotation/network_traffic_annotation.h" | 
|  | #include "ui/base/l10n/l10n_util.h" | 
|  |  | 
|  | #if BUILDFLAG(IS_WIN) | 
|  | #include "base/win/windows_types.h" | 
|  | #endif | 
|  |  | 
|  | using content::PluginService; | 
|  |  | 
|  | // PluginObserver ------------------------------------------------------------- | 
|  |  | 
|  | void PluginObserver::BindPluginHost( | 
|  | mojo::PendingAssociatedReceiver<chrome::mojom::PluginHost> receiver, | 
|  | content::RenderFrameHost* rfh) { | 
|  | auto* web_contents = content::WebContents::FromRenderFrameHost(rfh); | 
|  | if (!web_contents) | 
|  | return; | 
|  | auto* plugin_helper = PluginObserver::FromWebContents(web_contents); | 
|  | if (!plugin_helper) | 
|  | return; | 
|  | plugin_helper->plugin_host_receivers_.Bind(rfh, std::move(receiver)); | 
|  | } | 
|  |  | 
|  | PluginObserver::PluginObserver(content::WebContents* web_contents) | 
|  | : content::WebContentsObserver(web_contents), | 
|  | content::WebContentsUserData<PluginObserver>(*web_contents), | 
|  | plugin_host_receivers_(web_contents, this) {} | 
|  |  | 
|  | PluginObserver::~PluginObserver() = default; | 
|  |  | 
|  | // static | 
|  | void PluginObserver::CreatePluginObserverInfoBar( | 
|  | infobars::ContentInfoBarManager* infobar_manager, | 
|  | const std::u16string& plugin_name) { | 
|  | CreateSimpleAlertInfoBar( | 
|  | infobar_manager, | 
|  | infobars::InfoBarDelegate::PLUGIN_OBSERVER_INFOBAR_DELEGATE, | 
|  | &kExtensionCrashedIcon, | 
|  | l10n_util::GetStringFUTF16(IDS_PLUGIN_INITIALIZATION_ERROR_PROMPT, | 
|  | plugin_name)); | 
|  | } | 
|  |  | 
|  | void PluginObserver::CouldNotLoadPlugin(const base::FilePath& plugin_path) { | 
|  | std::u16string plugin_name = | 
|  | PluginService::GetInstance()->GetPluginDisplayNameByPath(plugin_path); | 
|  | CreatePluginObserverInfoBar( | 
|  | infobars::ContentInfoBarManager::FromWebContents(web_contents()), | 
|  | plugin_name); | 
|  | } | 
|  |  | 
|  | void PluginObserver::OpenPDF(const GURL& url) { | 
|  | content::RenderFrameHost* render_frame_host = | 
|  | plugin_host_receivers_.GetCurrentTargetFrame(); | 
|  | // WebViews should never trigger PDF downloads. | 
|  | if (extensions::WebViewGuest::FromRenderFrameHost(render_frame_host)) | 
|  | return; | 
|  |  | 
|  | content::Referrer referrer; | 
|  | if (!CanOpenPdfUrl(render_frame_host, url, | 
|  | web_contents()->GetLastCommittedURL(), &referrer)) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | net::NetworkTrafficAnnotationTag traffic_annotation = | 
|  | net::DefineNetworkTrafficAnnotation("pdf_plugin_placeholder", R"( | 
|  | semantics { | 
|  | sender: "PDF Plugin Placeholder" | 
|  | description: | 
|  | "When the PDF Viewer is unavailable, a placeholder is shown for " | 
|  | "embedded PDFs. This placeholder allows the user to download and " | 
|  | "open the PDF file via a button." | 
|  | trigger: | 
|  | "The user clicks the 'View PDF' button in the PDF placeholder." | 
|  | data: "None." | 
|  | destination: WEBSITE | 
|  | } | 
|  | policy { | 
|  | cookies_allowed: NO | 
|  | setting: | 
|  | "This feature can be disabled via 'Download PDF files instead of " | 
|  | "automatically opening them in Chrome' in settings under content. " | 
|  | "The feature is disabled by default." | 
|  | chrome_policy { | 
|  | AlwaysOpenPdfExternally { | 
|  | AlwaysOpenPdfExternally: false | 
|  | } | 
|  | } | 
|  | })"); | 
|  | std::unique_ptr<download::DownloadUrlParameters> params = | 
|  | std::make_unique<download::DownloadUrlParameters>( | 
|  | url, | 
|  | render_frame_host->GetRenderViewHost() | 
|  | ->GetProcess() | 
|  | ->GetDeprecatedID(), | 
|  | render_frame_host->GetRoutingID(), traffic_annotation); | 
|  | params->set_referrer(referrer.url); | 
|  | params->set_referrer_policy( | 
|  | content::Referrer::ReferrerPolicyForUrlRequest(referrer.policy)); | 
|  |  | 
|  | web_contents()->GetBrowserContext()->GetDownloadManager()->DownloadUrl( | 
|  | std::move(params)); | 
|  | } | 
|  |  | 
|  | WEB_CONTENTS_USER_DATA_KEY_IMPL(PluginObserver); |