// 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;

DEFINE_WEB_CONTENTS_USER_DATA_KEY(PluginObserver);

// 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("Plugin.ShowDisconnectedInfobar", 1);
  } else {
    infobar_text = l10n_util::GetStringFUTF16(IDS_PLUGIN_CRASHED_PROMPT,
                                              plugin_name);
    UMA_HISTOGRAM_COUNTS("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("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::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);
}
