// 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/extensions/tab_helper.h"

#include "base/bind.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "chrome/browser/banners/app_banner_manager_desktop.h"
#include "chrome/browser/extensions/activity_log/activity_log.h"
#include "chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h"
#include "chrome/browser/extensions/api/declarative_content/chrome_content_rules_registry.h"
#include "chrome/browser/extensions/bookmark_app_helper.h"
#include "chrome/browser/extensions/chrome_extension_web_contents_observer.h"
#include "chrome/browser/extensions/extension_action_runner.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/extensions/install_observer.h"
#include "chrome/browser/extensions/install_tracker.h"
#include "chrome/browser/extensions/install_tracker_factory.h"
#include "chrome/browser/installable/installable_metrics.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sessions/session_tab_helper.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/web_applications/components/web_app_helpers.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h"
#include "content/public/browser/invalidate_type.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.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/common/frame_navigate_params.h"
#include "extensions/browser/api/declarative/rules_registry_service.h"
#include "extensions/browser/disable_reason.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/extension_web_contents_observer.h"
#include "extensions/browser/image_loader.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_icon_set.h"
#include "extensions/common/extension_messages.h"
#include "extensions/common/extension_resource.h"
#include "extensions/common/extension_urls.h"
#include "extensions/common/feature_switch.h"
#include "extensions/common/manifest_handlers/icons_handler.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/manifest/web_display_mode.h"
#include "url/url_constants.h"

using content::NavigationController;
using content::NavigationEntry;
using content::WebContents;

namespace extensions {

TabHelper::~TabHelper() = default;

TabHelper::TabHelper(content::WebContents* web_contents)
    : content::WebContentsObserver(web_contents),
      profile_(Profile::FromBrowserContext(web_contents->GetBrowserContext())),
      extension_app_(NULL),
      pending_web_app_action_(NONE),
      last_committed_nav_entry_unique_id_(0),
      script_executor_(new ScriptExecutor(web_contents)),
      extension_action_runner_(new ExtensionActionRunner(web_contents)),
      registry_observer_(this),
      image_loader_ptr_factory_(this),
      weak_ptr_factory_(this) {
  // The ActiveTabPermissionManager requires a session ID; ensure this
  // WebContents has one.
  SessionTabHelper::CreateForWebContents(web_contents);
  // The Unretained() is safe because ForEachFrame() is synchronous.
  web_contents->ForEachFrame(
      base::BindRepeating(&TabHelper::SetTabId, base::Unretained(this)));
  active_tab_permission_granter_.reset(new ActiveTabPermissionGranter(
      web_contents, SessionTabHelper::IdForTab(web_contents).id(), profile_));

  ActivityLog::GetInstance(profile_)->ObserveScripts(script_executor_.get());

  InvokeForContentRulesRegistries([this](ContentRulesRegistry* registry) {
    registry->MonitorWebContentsForRuleEvaluation(this->web_contents());
  });

  // We need an ExtensionWebContentsObserver, so make sure one exists (this is
  // a no-op if one already does).
  ChromeExtensionWebContentsObserver::CreateForWebContents(web_contents);
  ExtensionWebContentsObserver::GetForWebContents(web_contents)->dispatcher()->
      set_delegate(this);

  BookmarkManagerPrivateDragEventRouter::CreateForWebContents(web_contents);
}

void TabHelper::CreateHostedAppFromWebContents(bool shortcut_app_requested,
                                               OnceInstallCallback callback) {
  DCHECK(CanCreateBookmarkApp());
  if (pending_web_app_action_ != NONE)
    return;

  install_callback_ = std::move(callback);

  // Start fetching web app info for CreateApplicationShortcut dialog and show
  // the dialog when the data is available in OnDidGetWebApplicationInfo.
  GetApplicationInfo(CREATE_HOSTED_APP, shortcut_app_requested);
}

bool TabHelper::CanCreateBookmarkApp() const {
  return !profile_->IsGuestSession() && !profile_->IsOffTheRecord() &&
         !profile_->IsSystemProfile() &&
         IsValidBookmarkAppUrl(web_contents()->GetURL());
}

void TabHelper::SetExtensionApp(const Extension* extension) {
  DCHECK(!extension || AppLaunchInfo::GetFullLaunchURL(extension).is_valid());
  if (extension_app_ == extension)
    return;

  extension_app_ = extension;

  if (extension_app_) {
    registry_observer_.Add(
        ExtensionRegistry::Get(web_contents()->GetBrowserContext()));
  } else {
    registry_observer_.RemoveAll();
  }

  UpdateExtensionAppIcon(extension_app_);

  if (extension_app_) {
    SessionTabHelper::FromWebContents(web_contents())
        ->SetTabExtensionAppID(GetAppId());
  }
}

void TabHelper::SetExtensionAppById(const ExtensionId& extension_app_id) {
  const Extension* extension = GetExtension(extension_app_id);
  if (extension)
    SetExtensionApp(extension);
}

ExtensionId TabHelper::GetAppId() const {
  return extension_app_ ? extension_app_->id() : ExtensionId();
}

SkBitmap* TabHelper::GetExtensionAppIcon() {
  if (extension_app_icon_.empty())
    return nullptr;

  return &extension_app_icon_;
}

// Encapsulates the logic to decide which ContentRulesRegistries need to be
// invoked, depending on whether this WebContents is associated with an Original
// or OffTheRecord profile. In the latter case, we need to invoke on both the
// Original and OffTheRecord ContentRulesRegistries since the Original registry
// handles spanning-mode incognito extensions.
template <class Func>
void TabHelper::InvokeForContentRulesRegistries(const Func& func) {
  RulesRegistryService* rules_registry_service =
      RulesRegistryService::Get(profile_);
  if (rules_registry_service) {
    func(rules_registry_service->content_rules_registry());
    if (profile_->IsOffTheRecord()) {
      // The original profile's content rules registry handles rules for
      // spanning extensions in incognito profiles, so invoke it also.
      RulesRegistryService* original_profile_rules_registry_service =
          RulesRegistryService::Get(profile_->GetOriginalProfile());
      DCHECK_NE(rules_registry_service,
                original_profile_rules_registry_service);
      if (original_profile_rules_registry_service)
        func(original_profile_rules_registry_service->content_rules_registry());
    }
  }
}

void TabHelper::FinishCreateBookmarkApp(
    const Extension* extension,
    const WebApplicationInfo& web_app_info) {
  // Send the 'appinstalled' event and ensure any beforeinstallpromptevent
  // cannot trigger installation again.
  if (banners::AppBannerManagerDesktop::IsEnabled() &&
      web_app_info.open_as_window) {
    banners::AppBannerManagerDesktop::FromWebContents(web_contents())
        ->OnInstall(false /* is_native app */,
                    blink::kWebDisplayModeStandalone);
  }
  pending_web_app_action_ = NONE;

  const bool success = !!extension;
  const ExtensionId app_id = extension ? extension->id() : ExtensionId();
  std::move(install_callback_).Run(app_id, success);
}

void TabHelper::RenderFrameCreated(content::RenderFrameHost* host) {
  SetTabId(host);
}

void TabHelper::DidFinishNavigation(
    content::NavigationHandle* navigation_handle) {
  if (!navigation_handle->IsInMainFrame() || !navigation_handle->HasCommitted())
    return;

  InvokeForContentRulesRegistries(
      [this, navigation_handle](ContentRulesRegistry* registry) {
    registry->DidFinishNavigation(web_contents(), navigation_handle);
  });

  content::BrowserContext* context = web_contents()->GetBrowserContext();
  ExtensionRegistry* registry = ExtensionRegistry::Get(context);
  const ExtensionSet& enabled_extensions = registry->enabled_extensions();

  if (util::IsNewBookmarkAppsEnabled()) {
    Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
    if (browser && browser->is_app()) {
      const Extension* extension = registry->GetExtensionById(
          web_app::GetAppIdFromApplicationName(browser->app_name()),
          ExtensionRegistry::EVERYTHING);
      if (extension && AppLaunchInfo::GetFullLaunchURL(extension).is_valid())
        SetExtensionApp(extension);
    } else {
      UpdateExtensionAppIcon(
          enabled_extensions.GetExtensionOrAppByURL(
              navigation_handle->GetURL()));
    }
  } else {
    UpdateExtensionAppIcon(
        enabled_extensions.GetExtensionOrAppByURL(navigation_handle->GetURL()));
  }
}

bool TabHelper::OnMessageReceived(const IPC::Message& message,
                                  content::RenderFrameHost* sender) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(TabHelper, message, sender)
    IPC_MESSAGE_HANDLER(ExtensionHostMsg_GetAppInstallState,
                        OnGetAppInstallState)
    IPC_MESSAGE_HANDLER(ExtensionHostMsg_ContentScriptsExecuting,
                        OnContentScriptsExecuting)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void TabHelper::DidCloneToNewWebContents(WebContents* old_web_contents,
                                         WebContents* new_web_contents) {
  // When the WebContents that this is attached to is cloned, give the new clone
  // a TabHelper and copy state over.
  CreateForWebContents(new_web_contents);
  TabHelper* new_helper = FromWebContents(new_web_contents);

  new_helper->SetExtensionApp(extension_app_);
  new_helper->extension_app_icon_ = extension_app_icon_;
}

void TabHelper::OnDidGetWebApplicationInfo(
    chrome::mojom::ChromeRenderFrameAssociatedPtr chrome_render_frame,
    bool shortcut_app_requested,
    const WebApplicationInfo& info) {
  web_app_info_ = info;

  content::WebContents* contents = web_contents();
  NavigationEntry* entry = contents->GetController().GetLastCommittedEntry();
  if (!entry || last_committed_nav_entry_unique_id_ != entry->GetUniqueID())
    return;
  last_committed_nav_entry_unique_id_ = 0;

  switch (pending_web_app_action_) {
    case CREATE_HOSTED_APP: {
      if (web_app_info_.app_url.is_empty())
        web_app_info_.app_url = contents->GetLastCommittedURL();

      if (web_app_info_.title.empty())
        web_app_info_.title = contents->GetTitle();
      if (web_app_info_.title.empty())
        web_app_info_.title = base::UTF8ToUTF16(web_app_info_.app_url.spec());

      bookmark_app_helper_.reset(
          new BookmarkAppHelper(profile_, web_app_info_, contents,
                                InstallableMetrics::GetInstallSource(
                                    contents, InstallTrigger::MENU)));
      if (shortcut_app_requested)
        bookmark_app_helper_->set_shortcut_app_requested();
      bookmark_app_helper_->Create(base::Bind(
          &TabHelper::FinishCreateBookmarkApp, weak_ptr_factory_.GetWeakPtr()));
      break;
    }
    default:
      NOTREACHED();
      break;
  }

  // The hosted app action will be cleared once the installation completes or
  // fails.
  if (pending_web_app_action_ != CREATE_HOSTED_APP)
    pending_web_app_action_ = NONE;
}

void TabHelper::OnGetAppInstallState(content::RenderFrameHost* host,
                                     const GURL& requestor_url,
                                     int return_route_id,
                                     int callback_id) {
  ExtensionRegistry* registry =
      ExtensionRegistry::Get(web_contents()->GetBrowserContext());
  const ExtensionSet& extensions = registry->enabled_extensions();
  const ExtensionSet& disabled_extensions = registry->disabled_extensions();

  std::string state;
  if (extensions.GetHostedAppByURL(requestor_url))
    state = extension_misc::kAppStateInstalled;
  else if (disabled_extensions.GetHostedAppByURL(requestor_url))
    state = extension_misc::kAppStateDisabled;
  else
    state = extension_misc::kAppStateNotInstalled;

  // We use the |host| to send the message because using
  // WebContentsObserver::Send() defaults to using the main RenderView, which
  // might be in a different process if the request came from a frame.
  host->Send(new ExtensionMsg_GetAppInstallStateResponse(return_route_id, state,
                                                         callback_id));
}

void TabHelper::OnContentScriptsExecuting(
    content::RenderFrameHost* host,
    const ExecutingScriptsMap& executing_scripts_map,
    const GURL& on_url) {
  ActivityLog::GetInstance(profile_)->OnScriptsExecuted(
      web_contents(), executing_scripts_map, on_url);
}

const Extension* TabHelper::GetExtension(const ExtensionId& extension_app_id) {
  if (extension_app_id.empty())
    return NULL;

  content::BrowserContext* context = web_contents()->GetBrowserContext();
  return ExtensionRegistry::Get(context)->enabled_extensions().GetByID(
      extension_app_id);
}

void TabHelper::UpdateExtensionAppIcon(const Extension* extension) {
  extension_app_icon_.reset();
  // Ensure previously enqueued callbacks are ignored.
  image_loader_ptr_factory_.InvalidateWeakPtrs();

  // Enqueue OnImageLoaded callback.
  if (extension) {
    ImageLoader* loader = ImageLoader::Get(profile_);
    loader->LoadImageAsync(
        extension,
        IconsInfo::GetIconResource(extension,
                                   extension_misc::EXTENSION_ICON_SMALL,
                                   ExtensionIconSet::MATCH_BIGGER),
        gfx::Size(extension_misc::EXTENSION_ICON_SMALL,
                  extension_misc::EXTENSION_ICON_SMALL),
        base::Bind(&TabHelper::OnImageLoaded,
                   image_loader_ptr_factory_.GetWeakPtr()));
  }
}

void TabHelper::OnImageLoaded(const gfx::Image& image) {
  if (!image.IsEmpty()) {
    extension_app_icon_ = *image.ToSkBitmap();
    web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TAB);
  }
}

WindowController* TabHelper::GetExtensionWindowController() const  {
  return ExtensionTabUtil::GetWindowControllerOfTab(web_contents());
}

WebContents* TabHelper::GetAssociatedWebContents() const {
  return web_contents();
}

void TabHelper::OnExtensionUnloaded(content::BrowserContext* browser_context,
                                    const Extension* extension,
                                    UnloadedExtensionReason reason) {
  DCHECK(extension_app_);
  if (extension == extension_app_)
    SetExtensionApp(nullptr);
}

void TabHelper::GetApplicationInfo(WebAppAction action,
                                   bool shortcut_app_requested) {
  NavigationEntry* entry =
      web_contents()->GetController().GetLastCommittedEntry();
  if (!entry)
    return;

  // This DCHECK added to ensure this function is called only once.
  DCHECK_EQ(pending_web_app_action_, NONE);

  pending_web_app_action_ = action;
  last_committed_nav_entry_unique_id_ = entry->GetUniqueID();

  chrome::mojom::ChromeRenderFrameAssociatedPtr chrome_render_frame;
  web_contents()->GetMainFrame()->GetRemoteAssociatedInterfaces()->GetInterface(
      &chrome_render_frame);
  // Bind the InterfacePtr into the callback so that it's kept alive
  // until there's either a connection error or a response.
  auto* web_app_info_proxy = chrome_render_frame.get();
  web_app_info_proxy->GetWebApplicationInfo(
      base::Bind(&TabHelper::OnDidGetWebApplicationInfo, base::Unretained(this),
                 base::Passed(&chrome_render_frame), shortcut_app_requested));
}

void TabHelper::SetTabId(content::RenderFrameHost* render_frame_host) {
  render_frame_host->Send(new ExtensionMsg_SetTabId(
      render_frame_host->GetRoutingID(),
      SessionTabHelper::IdForTab(web_contents()).id()));
}

}  // namespace extensions
