// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// 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/auto_reset.h"
#include "base/bind.h"
#include "base/debug/crash_logging.h"
#include "base/metrics/histogram_macros.h"
#include "build/build_config.h"
#include "chrome/app/vector_icons/vector_icons.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/plugins/flash_download_interception.h"
#include "chrome/browser/plugins/plugin_finder.h"
#include "chrome/browser/plugins/plugin_infobar_delegates.h"
#include "chrome/browser/plugins/plugin_installer.h"
#include "chrome/browser/plugins/plugin_installer_observer.h"
#include "chrome/browser/plugins/reload_plugin_infobar_delegate.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/tab_modal_confirm_dialog.h"
#include "chrome/browser/ui/tab_modal_confirm_dialog_delegate.h"
#include "chrome/common/buildflags.h"
#include "chrome/common/render_messages.h"
#include "chrome/grit/generated_resources.h"
#include "components/component_updater/component_updater_service.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/infobars/core/simple_alert_infobar_delegate.h"
#include "components/metrics_services_manager/metrics_services_manager.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/browser/render_frame_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 "services/service_manager/public/cpp/interface_provider.h"
#include "ui/base/l10n/l10n_util.h"

using content::PluginService;

// PluginObserver -------------------------------------------------------------

class PluginObserver::PluginPlaceholderHost : public PluginInstallerObserver {
 public:
  PluginPlaceholderHost(
      PluginObserver* observer,
      base::string16 plugin_name,
      PluginInstaller* installer,
      chrome::mojom::PluginRendererPtr plugin_renderer_interface)
      : PluginInstallerObserver(installer),
        observer_(observer),
        plugin_renderer_interface_(std::move(plugin_renderer_interface)) {
    plugin_renderer_interface_.set_connection_error_handler(
        base::Bind(&PluginObserver::RemovePluginPlaceholderHost,
                   base::Unretained(observer_), this));
    DCHECK(installer);
  }

  void DownloadFinished() override {
    plugin_renderer_interface_->FinishedDownloading();
  }

 private:
  PluginObserver* observer_;
  chrome::mojom::PluginRendererPtr plugin_renderer_interface_;
};

class PluginObserver::ComponentObserver
    : public update_client::UpdateClient::Observer {
 public:
  using Events = update_client::UpdateClient::Observer::Events;
  ComponentObserver(PluginObserver* observer,
                    const std::string& component_id,
                    chrome::mojom::PluginRendererPtr plugin_renderer_interface)
      : observer_(observer),
        component_id_(component_id),
        plugin_renderer_interface_(std::move(plugin_renderer_interface)) {
    plugin_renderer_interface_.set_connection_error_handler(
        base::Bind(&PluginObserver::RemoveComponentObserver,
                   base::Unretained(observer_), this));
    g_browser_process->component_updater()->AddObserver(this);
  }

  ~ComponentObserver() override {
    g_browser_process->component_updater()->RemoveObserver(this);
  }

  void OnEvent(Events event, const std::string& id) override {
    // TODO(lukasza): https://crbug.com/760637: |routing_id_| might live in a
    // different process than the RenderViewHost - need to track and use
    // placeholder's process when calling Send below.

    if (id != component_id_)
      return;
    switch (event) {
      case Events::COMPONENT_UPDATED:
        plugin_renderer_interface_->UpdateSuccess();
        observer_->RemoveComponentObserver(this);
        break;
      case Events::COMPONENT_UPDATE_FOUND:
        plugin_renderer_interface_->UpdateDownloading();
        break;
      case Events::COMPONENT_NOT_UPDATED:
      case Events::COMPONENT_UPDATE_ERROR:
        plugin_renderer_interface_->UpdateFailure();
        observer_->RemoveComponentObserver(this);
        break;
      default:
        // No message to send.
        break;
    }
  }

 private:
  PluginObserver* observer_;
  std::string component_id_;
  chrome::mojom::PluginRendererPtr plugin_renderer_interface_;
  DISALLOW_COPY_AND_ASSIGN(ComponentObserver);
};

PluginObserver::PluginObserver(content::WebContents* web_contents)
    : content::WebContentsObserver(web_contents),
      plugin_host_bindings_(web_contents, this),
      weak_ptr_factory_(this) {}

PluginObserver::~PluginObserver() {
}

void PluginObserver::PluginCrashed(const base::FilePath& plugin_path,
                                   base::ProcessId plugin_pid) {
  DCHECK(!plugin_path.value().empty());

  base::string16 plugin_name =
      PluginService::GetInstance()->GetPluginDisplayNameByPath(plugin_path);
  base::string16 infobar_text;
#if defined(OS_WIN)
  // Find out whether the plugin process is still alive.
  // Note: Although the chances are slim, it is possible that after the plugin
  // process died, |plugin_pid| has been reused by a new process. The
  // consequence is that we will display |IDS_PLUGIN_DISCONNECTED_PROMPT| rather
  // than |IDS_PLUGIN_CRASHED_PROMPT| to the user, which seems acceptable.
  base::Process plugin_process =
      base::Process::OpenWithAccess(plugin_pid,
                                    PROCESS_QUERY_INFORMATION | SYNCHRONIZE);
  bool is_running = false;
  if (plugin_process.IsValid()) {
    int unused_exit_code = 0;
    is_running = base::GetTerminationStatus(plugin_process.Handle(),
                                            &unused_exit_code) ==
                 base::TERMINATION_STATUS_STILL_RUNNING;
    plugin_process.Close();
  }

  if (is_running) {
    infobar_text = l10n_util::GetStringFUTF16(IDS_PLUGIN_DISCONNECTED_PROMPT,
                                              plugin_name);
    UMA_HISTOGRAM_COUNTS_1M("Plugin.ShowDisconnectedInfobar", 1);
  } else {
    infobar_text = l10n_util::GetStringFUTF16(IDS_PLUGIN_CRASHED_PROMPT,
                                              plugin_name);
    UMA_HISTOGRAM_COUNTS_1M("Plugin.ShowCrashedInfobar", 1);
  }
#else
  // Calling the POSIX version of base::GetTerminationStatus() may affect other
  // code which is interested in the process termination status. (Please see the
  // comment of the function.) Therefore, a better way is needed to distinguish
  // disconnections from crashes.
  infobar_text = l10n_util::GetStringFUTF16(IDS_PLUGIN_CRASHED_PROMPT,
                                            plugin_name);
  UMA_HISTOGRAM_COUNTS_1M("Plugin.ShowCrashedInfobar", 1);
#endif

  ReloadPluginInfoBarDelegate::Create(
      InfoBarService::FromWebContents(web_contents()),
      &web_contents()->GetController(),
      infobar_text);
}

// static
void PluginObserver::CreatePluginObserverInfoBar(
    InfoBarService* infobar_service,
    const base::string16& plugin_name) {
  SimpleAlertInfoBarDelegate::Create(
      infobar_service,
      infobars::InfoBarDelegate::PLUGIN_OBSERVER_INFOBAR_DELEGATE,
      &kExtensionCrashedIcon,
      l10n_util::GetStringFUTF16(IDS_PLUGIN_INITIALIZATION_ERROR_PROMPT,
                                 plugin_name),
      true);
}

void PluginObserver::BlockedOutdatedPlugin(
    chrome::mojom::PluginRendererPtr plugin_renderer,
    const std::string& identifier) {
  PluginFinder* finder = PluginFinder::GetInstance();
  // Find plugin to update.
  PluginInstaller* installer = NULL;
  std::unique_ptr<PluginMetadata> plugin;
  if (finder->FindPluginWithIdentifier(identifier, &installer, &plugin)) {
    auto plugin_placeholder = std::make_unique<PluginPlaceholderHost>(
        this, plugin->name(), installer, std::move(plugin_renderer));
    plugin_placeholders_[plugin_placeholder.get()] =
        std::move(plugin_placeholder);

    OutdatedPluginInfoBarDelegate::Create(
        InfoBarService::FromWebContents(web_contents()), installer,
        std::move(plugin));
  } else {
    NOTREACHED();
  }
}

void PluginObserver::BlockedComponentUpdatedPlugin(
    chrome::mojom::PluginRendererPtr plugin_renderer,
    const std::string& identifier) {
  auto component_observer = std::make_unique<ComponentObserver>(
      this, identifier, std::move(plugin_renderer));
  component_observers_[component_observer.get()] =
      std::move(component_observer);
  g_browser_process->component_updater()->GetOnDemandUpdater().OnDemandUpdate(
      identifier, component_updater::OnDemandUpdater::Priority::FOREGROUND,
      component_updater::Callback());
}

void PluginObserver::RemoveComponentObserver(
    ComponentObserver* component_observer) {
  component_observers_.erase(component_observer);
}

void PluginObserver::RemovePluginPlaceholderHost(
    PluginPlaceholderHost* placeholder) {
  plugin_placeholders_.erase(placeholder);
}

void PluginObserver::ShowFlashPermissionBubble() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  FlashDownloadInterception::InterceptFlashDownloadNavigation(
      web_contents(), web_contents()->GetLastCommittedURL());
}

void PluginObserver::CouldNotLoadPlugin(const base::FilePath& plugin_path) {
  g_browser_process->GetMetricsServicesManager()->OnPluginLoadingError(
      plugin_path);
  base::string16 plugin_name =
      PluginService::GetInstance()->GetPluginDisplayNameByPath(plugin_path);
  CreatePluginObserverInfoBar(InfoBarService::FromWebContents(web_contents()),
                              plugin_name);
}

WEB_CONTENTS_USER_DATA_KEY_IMPL(PluginObserver)
