// Copyright 2013 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 "extensions/renderer/extension_frame_helper.h"

#include <set>

#include "base/metrics/histogram_macros.h"
#include "base/strings/string_util.h"
#include "base/timer/elapsed_timer.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_view.h"
#include "extensions/common/api/messaging/message.h"
#include "extensions/common/api/messaging/port_id.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension_messages.h"
#include "extensions/common/manifest_handlers/background_info.h"
#include "extensions/renderer/api/automation/automation_api_helper.h"
#include "extensions/renderer/console.h"
#include "extensions/renderer/dispatcher.h"
#include "extensions/renderer/extension_bindings_system.h"
#include "extensions/renderer/renderer_messaging_service.h"
#include "extensions/renderer/script_context.h"
#include "extensions/renderer/script_context_set.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/public/web/web_console_message.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_document_loader.h"
#include "third_party/blink/public/web/web_local_frame.h"

namespace extensions {

namespace {

constexpr int kMainWorldId = 0;

base::LazyInstance<std::set<const ExtensionFrameHelper*>>::DestructorAtExit
    g_frame_helpers = LAZY_INSTANCE_INITIALIZER;

// Returns true if the render frame corresponding with |frame_helper| matches
// the given criteria.
bool RenderFrameMatches(const ExtensionFrameHelper* frame_helper,
                        ViewType match_view_type,
                        int match_window_id,
                        int match_tab_id,
                        const std::string& match_extension_id) {
  if (match_view_type != VIEW_TYPE_INVALID &&
      frame_helper->view_type() != match_view_type)
    return false;

  // Not all frames have a valid ViewType, e.g. devtools, most GuestViews, and
  // unclassified detached WebContents.
  if (frame_helper->view_type() == VIEW_TYPE_INVALID)
    return false;

  // This logic matches ExtensionWebContentsObserver::GetExtensionFromFrame.
  blink::WebSecurityOrigin origin =
      frame_helper->render_frame()->GetWebFrame()->GetSecurityOrigin();
  if (origin.IsUnique() ||
      !base::EqualsASCII(origin.Protocol().Utf16(), kExtensionScheme) ||
      !base::EqualsASCII(origin.Host().Utf16(), match_extension_id.c_str()))
    return false;

  if (match_window_id != extension_misc::kUnknownWindowId &&
      frame_helper->browser_window_id() != match_window_id)
    return false;

  if (match_tab_id != extension_misc::kUnknownTabId &&
      frame_helper->tab_id() != match_tab_id)
    return false;

  return true;
}

// Runs every callback in |callbacks_to_be_run_and_cleared| while |frame_helper|
// is valid, and clears |callbacks_to_be_run_and_cleared|.
void RunCallbacksWhileFrameIsValid(
    base::WeakPtr<ExtensionFrameHelper> frame_helper,
    std::vector<base::Closure>* callbacks_to_be_run_and_cleared) {
  // The JavaScript code can cause re-entrancy. To avoid a deadlock, don't run
  // callbacks that are added during the iteration.
  std::vector<base::Closure> callbacks;
  callbacks_to_be_run_and_cleared->swap(callbacks);
  for (auto& callback : callbacks) {
    callback.Run();
    if (!frame_helper.get())
      return;  // Frame and ExtensionFrameHelper invalidated by callback.
  }
}

enum class PortType {
  EXTENSION,
  TAB,
  NATIVE_APP,
};

// Returns an extension hosted in the |render_frame| (or nullptr if the frame
// doesn't host an extension).
const Extension* GetExtensionFromFrame(content::RenderFrame* render_frame) {
  DCHECK(render_frame);
  ScriptContext* context =
      ScriptContextSet::GetMainWorldContextForFrame(render_frame);
  return context ? context->effective_extension() : nullptr;
}

}  // namespace

ExtensionFrameHelper::ExtensionFrameHelper(content::RenderFrame* render_frame,
                                           Dispatcher* extension_dispatcher)
    : content::RenderFrameObserver(render_frame),
      content::RenderFrameObserverTracker<ExtensionFrameHelper>(render_frame),
      view_type_(VIEW_TYPE_INVALID),
      tab_id_(-1),
      browser_window_id_(-1),
      extension_dispatcher_(extension_dispatcher),
      did_create_current_document_element_(false),
      weak_ptr_factory_(this) {
  g_frame_helpers.Get().insert(this);
  if (render_frame->IsMainFrame()) {
    // Manages its own lifetime.
    new AutomationApiHelper(render_frame);
  }
}

ExtensionFrameHelper::~ExtensionFrameHelper() {
  g_frame_helpers.Get().erase(this);
}

// static
std::vector<content::RenderFrame*> ExtensionFrameHelper::GetExtensionFrames(
    const std::string& extension_id,
    int browser_window_id,
    int tab_id,
    ViewType view_type) {
  std::vector<content::RenderFrame*> render_frames;
  for (const ExtensionFrameHelper* helper : g_frame_helpers.Get()) {
    if (RenderFrameMatches(helper, view_type, browser_window_id, tab_id,
                           extension_id))
      render_frames.push_back(helper->render_frame());
  }
  return render_frames;
}

// static
v8::Local<v8::Array> ExtensionFrameHelper::GetV8MainFrames(
    v8::Local<v8::Context> context,
    const std::string& extension_id,
    int browser_window_id,
    int tab_id,
    ViewType view_type) {
  // WebFrame::ScriptCanAccess uses the isolate's current context. We need to
  // make sure that the current context is the one we're expecting.
  DCHECK(context == context->GetIsolate()->GetCurrentContext());
  std::vector<content::RenderFrame*> render_frames =
      GetExtensionFrames(extension_id, browser_window_id, tab_id, view_type);
  v8::Local<v8::Array> v8_frames = v8::Array::New(context->GetIsolate());

  int v8_index = 0;
  for (content::RenderFrame* frame : render_frames) {
    if (!frame->IsMainFrame())
      continue;

    blink::WebLocalFrame* web_frame = frame->GetWebFrame();
    if (!blink::WebFrame::ScriptCanAccess(web_frame))
      continue;

    v8::Local<v8::Context> frame_context = web_frame->MainWorldScriptContext();
    if (!frame_context.IsEmpty()) {
      v8::Local<v8::Value> window = frame_context->Global();
      CHECK(!window.IsEmpty());
      v8::Maybe<bool> maybe =
          v8_frames->CreateDataProperty(context, v8_index++, window);
      CHECK(maybe.IsJust() && maybe.FromJust());
    }
  }

  return v8_frames;
}

// static
content::RenderFrame* ExtensionFrameHelper::GetBackgroundPageFrame(
    const std::string& extension_id) {
  for (const ExtensionFrameHelper* helper : g_frame_helpers.Get()) {
    if (RenderFrameMatches(helper, VIEW_TYPE_EXTENSION_BACKGROUND_PAGE,
                           extension_misc::kUnknownWindowId,
                           extension_misc::kUnknownTabId, extension_id)) {
      blink::WebLocalFrame* web_frame = helper->render_frame()->GetWebFrame();
      // Check if this is the top frame.
      if (web_frame->Top() == web_frame)
        return helper->render_frame();
    }
  }
  return nullptr;
}

v8::Local<v8::Value> ExtensionFrameHelper::GetV8BackgroundPageMainFrame(
    v8::Isolate* isolate,
    const std::string& extension_id) {
  content::RenderFrame* main_frame = GetBackgroundPageFrame(extension_id);

  v8::Local<v8::Value> background_page;
  blink::WebLocalFrame* web_frame =
      main_frame ? main_frame->GetWebFrame() : nullptr;
  if (web_frame && blink::WebFrame::ScriptCanAccess(web_frame))
    background_page = web_frame->MainWorldScriptContext()->Global();
  else
    background_page = v8::Undefined(isolate);

  return background_page;
}

// static
content::RenderFrame* ExtensionFrameHelper::FindFrame(
    content::RenderFrame* relative_to_frame,
    const std::string& name) {
  // Only pierce browsing instance boundaries if |relative_to_frame| is an
  // extension.
  const Extension* extension = GetExtensionFromFrame(relative_to_frame);
  if (!extension)
    return nullptr;

  for (const ExtensionFrameHelper* target : g_frame_helpers.Get()) {
    // Skip frames with a mismatched name.
    if (target->render_frame()->GetWebFrame()->AssignedName().Utf8() != name)
      continue;

    // Only pierce browsing instance boundaries if the target frame is from the
    // same extension (but not when another extension shares the same renderer
    // process because of reuse trigerred by process limit).
    if (extension != GetExtensionFromFrame(target->render_frame()))
      continue;

    // TODO(lukasza): https://crbug.com/764487: Investigate if we can further
    // restrict scenarios that allow piercing of browsing instance boundaries.
    // We hope that the piercing is only needed if the source or target frames
    // are for background contents or background page.
    ViewType target_view_type = target->view_type();
    ViewType source_view_type =
        ExtensionFrameHelper::Get(relative_to_frame)->view_type();
    UMA_HISTOGRAM_ENUMERATION(
        "Extensions.BrowsingInstanceViolation.ExtensionType",
        extension->GetType(), Manifest::NUM_LOAD_TYPES);
    UMA_HISTOGRAM_ENUMERATION(
        "Extensions.BrowsingInstanceViolation.SourceExtensionViewType",
        source_view_type, VIEW_TYPE_LAST + 1);
    UMA_HISTOGRAM_ENUMERATION(
        "Extensions.BrowsingInstanceViolation.TargetExtensionViewType",
        target_view_type, VIEW_TYPE_LAST + 1);
    bool is_background_source_or_target =
        source_view_type == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE ||
        source_view_type == VIEW_TYPE_BACKGROUND_CONTENTS ||
        target_view_type == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE ||
        target_view_type == VIEW_TYPE_BACKGROUND_CONTENTS;
    UMA_HISTOGRAM_BOOLEAN(
        "Extensions.BrowsingInstanceViolation.IsBackgroundSourceOrTarget",
        is_background_source_or_target);

    return target->render_frame();
  }

  return nullptr;
}

// static
bool ExtensionFrameHelper::IsContextForEventPage(const ScriptContext* context) {
  content::RenderFrame* render_frame = context->GetRenderFrame();
  return context->extension() && render_frame &&
         BackgroundInfo::HasLazyBackgroundPage(context->extension()) &&
         ExtensionFrameHelper::Get(render_frame)->view_type() ==
              VIEW_TYPE_EXTENSION_BACKGROUND_PAGE;
}

void ExtensionFrameHelper::DidCreateDocumentElement() {
  did_create_current_document_element_ = true;
  extension_dispatcher_->DidCreateDocumentElement(
      render_frame()->GetWebFrame());
}

void ExtensionFrameHelper::DidCreateNewDocument() {
  did_create_current_document_element_ = false;
}

void ExtensionFrameHelper::RunScriptsAtDocumentStart() {
  DCHECK(did_create_current_document_element_);
  RunCallbacksWhileFrameIsValid(weak_ptr_factory_.GetWeakPtr(),
                                &document_element_created_callbacks_);
  // |this| might be dead by now.
}

void ExtensionFrameHelper::RunScriptsAtDocumentEnd() {
  RunCallbacksWhileFrameIsValid(weak_ptr_factory_.GetWeakPtr(),
                                &document_load_finished_callbacks_);
  // |this| might be dead by now.
}

void ExtensionFrameHelper::RunScriptsAtDocumentIdle() {
  RunCallbacksWhileFrameIsValid(weak_ptr_factory_.GetWeakPtr(),
                                &document_idle_callbacks_);
  // |this| might be dead by now.
}

void ExtensionFrameHelper::ScheduleAtDocumentStart(
    const base::Closure& callback) {
  document_element_created_callbacks_.push_back(callback);
}

void ExtensionFrameHelper::ScheduleAtDocumentEnd(
    const base::Closure& callback) {
  document_load_finished_callbacks_.push_back(callback);
}

void ExtensionFrameHelper::ScheduleAtDocumentIdle(
    const base::Closure& callback) {
  document_idle_callbacks_.push_back(callback);
}

void ExtensionFrameHelper::DidStartProvisionalLoad(
    blink::WebDocumentLoader* document_loader) {
  // New window created by chrome.app.window.create() must not start parsing the
  // document immediately. The chrome.app.window.create() callback (if any)
  // needs to be called prior to the new window's 'load' event. The parser will
  // be resumed when it happens. It doesn't apply to sandboxed pages.
  if (view_type_ == VIEW_TYPE_APP_WINDOW && render_frame()->IsMainFrame() &&
      !has_started_first_navigation_ &&
      GURL(document_loader->GetRequest().Url()).SchemeIs(kExtensionScheme) &&
      !ScriptContext::IsSandboxedPage(document_loader->GetRequest().Url())) {
    document_loader->BlockParser();
  }

  has_started_first_navigation_ = true;

  if (!delayed_main_world_script_initialization_)
    return;

  delayed_main_world_script_initialization_ = false;
  v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
  v8::Local<v8::Context> context =
      render_frame()->GetWebFrame()->MainWorldScriptContext();
  v8::Context::Scope context_scope(context);
  extension_dispatcher_->DidCreateScriptContext(render_frame()->GetWebFrame(),
                                                context, kMainWorldId);
  // TODO(devlin): Add constants for main world id, no extension group.
}

void ExtensionFrameHelper::DidCreateScriptContext(
    v8::Local<v8::Context> context,
    int world_id) {
  if (world_id == kMainWorldId &&
      render_frame()->IsBrowserSideNavigationPending()) {
    DCHECK(!delayed_main_world_script_initialization_);
    // Defer initializing the extensions script context now because it depends
    // on having the URL of the provisional load which isn't available at this
    // point with PlzNavigate.
    delayed_main_world_script_initialization_ = true;
  } else {
    extension_dispatcher_->DidCreateScriptContext(render_frame()->GetWebFrame(),
                                                  context, world_id);
  }
}

void ExtensionFrameHelper::WillReleaseScriptContext(
    v8::Local<v8::Context> context,
    int world_id) {
  extension_dispatcher_->WillReleaseScriptContext(
      render_frame()->GetWebFrame(), context, world_id);
}

bool ExtensionFrameHelper::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(ExtensionFrameHelper, message)
    IPC_MESSAGE_HANDLER(ExtensionMsg_ValidateMessagePort,
                        OnExtensionValidateMessagePort)
    IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnConnect,
                        OnExtensionDispatchOnConnect)
    IPC_MESSAGE_HANDLER(ExtensionMsg_DeliverMessage, OnExtensionDeliverMessage)
    IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnDisconnect,
                        OnExtensionDispatchOnDisconnect)
    IPC_MESSAGE_HANDLER(ExtensionMsg_SetTabId, OnExtensionSetTabId)
    IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateBrowserWindowId,
                        OnUpdateBrowserWindowId)
    IPC_MESSAGE_HANDLER(ExtensionMsg_NotifyRenderViewType,
                        OnNotifyRendererViewType)
    IPC_MESSAGE_HANDLER(ExtensionMsg_Response, OnExtensionResponse)
    IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnExtensionMessageInvoke)
    IPC_MESSAGE_HANDLER(ExtensionMsg_SetFrameName, OnSetFrameName)
    IPC_MESSAGE_HANDLER(ExtensionMsg_AppWindowClosed, OnAppWindowClosed)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void ExtensionFrameHelper::OnExtensionValidateMessagePort(const PortId& id) {
  extension_dispatcher_->bindings_system()
      ->GetMessagingService()
      ->ValidateMessagePort(extension_dispatcher_->script_context_set(), id,
                            render_frame());
}

void ExtensionFrameHelper::OnExtensionDispatchOnConnect(
    const PortId& target_port_id,
    const std::string& channel_name,
    const ExtensionMsg_TabConnectionInfo& source,
    const ExtensionMsg_ExternalConnectionInfo& info,
    const std::string& tls_channel_id) {
  extension_dispatcher_->bindings_system()
      ->GetMessagingService()
      ->DispatchOnConnect(extension_dispatcher_->script_context_set(),
                          target_port_id, channel_name, source, info,
                          tls_channel_id, render_frame());
}

void ExtensionFrameHelper::OnExtensionDeliverMessage(const PortId& target_id,
                                                     const Message& message) {
  extension_dispatcher_->bindings_system()
      ->GetMessagingService()
      ->DeliverMessage(extension_dispatcher_->script_context_set(), target_id,
                       message, render_frame());
}

void ExtensionFrameHelper::OnExtensionDispatchOnDisconnect(
    const PortId& id,
    const std::string& error_message) {
  extension_dispatcher_->bindings_system()
      ->GetMessagingService()
      ->DispatchOnDisconnect(extension_dispatcher_->script_context_set(), id,
                             error_message, render_frame());
}

void ExtensionFrameHelper::OnExtensionSetTabId(int tab_id) {
  CHECK_EQ(tab_id_, -1);
  CHECK_GE(tab_id, 0);
  tab_id_ = tab_id;
}

void ExtensionFrameHelper::OnUpdateBrowserWindowId(int browser_window_id) {
  browser_window_id_ = browser_window_id;
}

void ExtensionFrameHelper::OnNotifyRendererViewType(ViewType type) {
  // TODO(devlin): It'd be really nice to be able to
  // DCHECK_EQ(VIEW_TYPE_INVALID, view_type_) here.
  view_type_ = type;
}

void ExtensionFrameHelper::OnExtensionResponse(int request_id,
                                               bool success,
                                               const base::ListValue& response,
                                               const std::string& error) {
  extension_dispatcher_->OnExtensionResponse(request_id,
                                             success,
                                             response,
                                             error);
}

void ExtensionFrameHelper::OnExtensionMessageInvoke(
    const std::string& extension_id,
    const std::string& module_name,
    const std::string& function_name,
    const base::ListValue& args) {
  extension_dispatcher_->InvokeModuleSystemMethod(
      render_frame(), extension_id, module_name, function_name, args);
}

void ExtensionFrameHelper::OnSetFrameName(const std::string& name) {
  render_frame()->GetWebFrame()->SetName(blink::WebString::FromUTF8(name));
}

void ExtensionFrameHelper::OnAppWindowClosed(bool send_onclosed) {
  DCHECK(render_frame()->IsMainFrame());

  if (!send_onclosed)
    return;

  v8::HandleScope scope(v8::Isolate::GetCurrent());
  v8::Local<v8::Context> v8_context =
      render_frame()->GetWebFrame()->MainWorldScriptContext();
  ScriptContext* script_context =
      ScriptContextSet::GetContextByV8Context(v8_context);
  if (!script_context)
    return;
  script_context->module_system()->CallModuleMethodSafe("app.window",
                                                        "onAppWindowClosed");
}

void ExtensionFrameHelper::OnDestruct() {
  delete this;
}

void ExtensionFrameHelper::DraggableRegionsChanged() {
  if (!render_frame()->IsMainFrame())
    return;

  blink::WebVector<blink::WebDraggableRegion> webregions =
      render_frame()->GetWebFrame()->GetDocument().DraggableRegions();
  std::vector<DraggableRegion> regions;
  for (blink::WebDraggableRegion& webregion : webregions) {
    render_frame()->GetRenderView()->ConvertViewportToWindowViaWidget(
        &webregion.bounds);

    regions.push_back(DraggableRegion());
    DraggableRegion& region = regions.back();
    region.bounds = webregion.bounds;
    region.draggable = webregion.draggable;
  }
  Send(new ExtensionHostMsg_UpdateDraggableRegions(routing_id(), regions));
}

}  // namespace extensions
