// 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 <stddef.h>
#include <stdint.h>
#include <tuple>

#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/values.h"
#include "build/build_config.h"
#include "cc/trees/layer_tree_host.h"
#include "content/child/request_extra_data.h"
#include "content/child/service_worker/service_worker_network_provider.h"
#include "content/common/accessibility_mode.h"
#include "content/common/content_switches_internal.h"
#include "content/common/frame_messages.h"
#include "content/common/frame_owner_properties.h"
#include "content/common/frame_replication_state.h"
#include "content/common/renderer.mojom.h"
#include "content/common/site_isolation_policy.h"
#include "content/common/view_messages.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/web_ui_controller_factory.h"
#include "content/public/common/bindings_policy.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/page_zoom.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
#include "content/public/renderer/content_renderer_client.h"
#include "content/public/renderer/document_state.h"
#include "content/public/renderer/navigation_state.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/frame_load_waiter.h"
#include "content/public/test/render_view_test.h"
#include "content/public/test/test_utils.h"
#include "content/renderer/accessibility/render_accessibility_impl.h"
#include "content/renderer/devtools/devtools_agent.h"
#include "content/renderer/gpu/render_widget_compositor.h"
#include "content/renderer/history_entry.h"
#include "content/renderer/history_serialization.h"
#include "content/renderer/navigation_state_impl.h"
#include "content/renderer/render_frame_proxy.h"
#include "content/renderer/render_process.h"
#include "content/renderer/render_view_impl.h"
#include "content/shell/browser/shell.h"
#include "content/shell/browser/shell_browser_context.h"
#include "content/test/mock_keyboard.h"
#include "content/test/test_render_frame.h"
#include "net/base/net_errors.h"
#include "net/cert/cert_status_flags.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebData.h"
#include "third_party/WebKit/public/platform/WebHTTPBody.h"
#include "third_party/WebKit/public/platform/WebRuntimeFeatures.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebURLResponse.h"
#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerNetworkProvider.h"
#include "third_party/WebKit/public/web/WebDataSource.h"
#include "third_party/WebKit/public/web/WebDeviceEmulationParams.h"
#include "third_party/WebKit/public/web/WebFrameContentDumper.h"
#include "third_party/WebKit/public/web/WebHistoryCommitType.h"
#include "third_party/WebKit/public/web/WebHistoryItem.h"
#include "third_party/WebKit/public/web/WebInputMethodController.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebPerformance.h"
#include "third_party/WebKit/public/web/WebScriptSource.h"
#include "third_party/WebKit/public/web/WebSettings.h"
#include "third_party/WebKit/public/web/WebView.h"
#include "third_party/WebKit/public/web/WebWindowFeatures.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/event.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/gfx/codec/jpeg_codec.h"
#include "ui/gfx/range/range.h"
#include "ui/native_theme/native_theme_features.h"

#if defined(OS_WIN)
#include "base/win/windows_version.h"
#endif

#if defined(USE_AURA) && defined(USE_X11)
#include <X11/Xlib.h>
#include "base/memory/ptr_util.h"
#include "ui/events/event_constants.h"
#include "ui/events/keycodes/keyboard_code_conversion.h"
#include "ui/events/test/events_test_utils.h"
#include "ui/events/test/events_test_utils_x11.h"
#endif

#if defined(USE_OZONE)
#include "ui/events/keycodes/keyboard_code_conversion.h"
#endif

#include "url/url_constants.h"

using base::TimeDelta;
using blink::WebFrame;
using blink::WebFrameContentDumper;
using blink::WebInputEvent;
using blink::WebLocalFrame;
using blink::WebMouseEvent;
using blink::WebRuntimeFeatures;
using blink::WebString;
using blink::WebTextDirection;
using blink::WebURLError;

namespace content {

namespace {

static const int kProxyRoutingId = 13;

#if (defined(USE_AURA) && defined(USE_X11)) || defined(USE_OZONE)
// Converts MockKeyboard::Modifiers to ui::EventFlags.
int ConvertMockKeyboardModifier(MockKeyboard::Modifiers modifiers) {
  static struct ModifierMap {
    MockKeyboard::Modifiers src;
    int dst;
  } kModifierMap[] = {
    { MockKeyboard::LEFT_SHIFT, ui::EF_SHIFT_DOWN },
    { MockKeyboard::RIGHT_SHIFT, ui::EF_SHIFT_DOWN },
    { MockKeyboard::LEFT_CONTROL, ui::EF_CONTROL_DOWN },
    { MockKeyboard::RIGHT_CONTROL, ui::EF_CONTROL_DOWN },
    { MockKeyboard::LEFT_ALT,  ui::EF_ALT_DOWN },
    { MockKeyboard::RIGHT_ALT, ui::EF_ALT_DOWN },
  };
  int flags = 0;
  for (size_t i = 0; i < arraysize(kModifierMap); ++i) {
    if (kModifierMap[i].src & modifiers) {
      flags |= kModifierMap[i].dst;
    }
  }
  return flags;
}
#endif

class WebUITestWebUIControllerFactory : public WebUIControllerFactory {
 public:
  WebUIController* CreateWebUIControllerForURL(WebUI* web_ui,
                                               const GURL& url) const override {
    return NULL;
  }
  WebUI::TypeID GetWebUIType(BrowserContext* browser_context,
                             const GURL& url) const override {
    return WebUI::kNoWebUI;
  }
  bool UseWebUIForURL(BrowserContext* browser_context,
                      const GURL& url) const override {
    return HasWebUIScheme(url);
  }
  bool UseWebUIBindingsForURL(BrowserContext* browser_context,
                              const GURL& url) const override {
    return HasWebUIScheme(url);
  }
};

// Timestamps logged close to each other under low resolution timers
// are more likely to record the same value. Allow for this by relaxing
// constraints on systems with these timers.
bool TimeTicksGT(const base::TimeTicks& x, const base::TimeTicks& y) {
  return base::TimeTicks::IsHighResolution() ? x > y : x >= y;
}

// FrameReplicationState is normally maintained in the browser process,
// but the function below provides a way for tests to construct a partial
// FrameReplicationState within the renderer process.  We say "partial",
// because some fields of FrameReplicationState cannot be filled out
// by content-layer, renderer code (still the constructed, partial
// FrameReplicationState is sufficiently complete to avoid trigerring
// asserts that a default/empty FrameReplicationState would).
FrameReplicationState ReconstructReplicationStateForTesting(
    TestRenderFrame* test_render_frame) {
  blink::WebLocalFrame* frame = test_render_frame->GetWebFrame();

  FrameReplicationState result;
  // can't recover result.scope - no way to get WebTreeScopeType via public
  // blink API...
  result.name = frame->AssignedName().Utf8();
  result.unique_name = test_render_frame->unique_name();
  result.sandbox_flags = frame->EffectiveSandboxFlags();
  // result.should_enforce_strict_mixed_content_checking is calculated in the
  // browser...
  result.origin = frame->GetSecurityOrigin();

  return result;
}

// Returns CommonNavigationParams for a normal navigation to a data: url, with
// navigation_start set to Now() plus the given offset.
CommonNavigationParams MakeCommonNavigationParams(
    TimeDelta navigation_start_offset) {
  CommonNavigationParams params;
  params.url = GURL("data:text/html,<div>Page</div>");
  params.navigation_start = base::TimeTicks::Now() + navigation_start_offset;
  params.navigation_type = FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT;
  params.transition = ui::PAGE_TRANSITION_TYPED;
  return params;
}

}  // namespace

class RenderViewImplTest : public RenderViewTest {
 public:
  RenderViewImplTest() {
    // Attach a pseudo keyboard device to this object.
    mock_keyboard_.reset(new MockKeyboard());
  }

  ~RenderViewImplTest() override {}

  void SetUp() override {
    // Enable Blink's experimental and test only features so that test code
    // does not have to bother enabling each feature.
    WebRuntimeFeatures::EnableExperimentalFeatures(true);
    WebRuntimeFeatures::EnableTestOnlyFeatures(true);
    WebRuntimeFeatures::EnableOverlayScrollbars(
        ui::IsOverlayScrollbarEnabled());
    RenderViewTest::SetUp();
  }

  RenderViewImpl* view() {
    return static_cast<RenderViewImpl*>(view_);
  }

  TestRenderFrame* frame() {
    return static_cast<TestRenderFrame*>(view()->GetMainRenderFrame());
  }

  void GoToOffsetWithParams(int offset,
                            const PageState& state,
                            const CommonNavigationParams common_params,
                            const StartNavigationParams start_params,
                            RequestNavigationParams request_params) {
    EXPECT_TRUE(common_params.transition & ui::PAGE_TRANSITION_FORWARD_BACK);
    int pending_offset = offset + view()->history_list_offset_;

    request_params.page_state = state;
    request_params.nav_entry_id = pending_offset + 1;
    request_params.pending_history_list_offset = pending_offset;
    request_params.current_history_list_offset = view()->history_list_offset_;
    request_params.current_history_list_length = view()->history_list_length_;
    frame()->Navigate(common_params, start_params, request_params);

    // The load actually happens asynchronously, so we pump messages to process
    // the pending continuation.
    FrameLoadWaiter(frame()).Wait();
  }

  template<class T>
  typename T::Param ProcessAndReadIPC() {
    base::RunLoop().RunUntilIdle();
    const IPC::Message* message =
        render_thread_->sink().GetUniqueMessageMatching(T::ID);
    typename T::Param param;
    EXPECT_TRUE(message);
    if (message)
      T::Read(message, &param);
    return param;
  }

  // Sends IPC messages that emulates a key-press event.
  int SendKeyEvent(MockKeyboard::Layout layout,
                   int key_code,
                   MockKeyboard::Modifiers modifiers,
                   base::string16* output) {
#if defined(OS_WIN)
    // Retrieve the Unicode character for the given tuple (keyboard-layout,
    // key-code, and modifiers).
    // Exit when a keyboard-layout driver cannot assign a Unicode character to
    // the tuple to prevent sending an invalid key code to the RenderView
    // object.
    CHECK(mock_keyboard_.get());
    CHECK(output);
    int length = mock_keyboard_->GetCharacters(layout, key_code, modifiers,
                                               output);
    if (length != 1)
      return -1;

    // Create IPC messages from Windows messages and send them to our
    // back-end.
    // A keyboard event of Windows consists of three Windows messages:
    // WM_KEYDOWN, WM_CHAR, and WM_KEYUP.
    // WM_KEYDOWN and WM_KEYUP sends virtual-key codes. On the other hand,
    // WM_CHAR sends a composed Unicode character.
    MSG msg1 = { NULL, WM_KEYDOWN, key_code, 0 };
    ui::KeyEvent evt1(msg1);
    NativeWebKeyboardEvent keydown_event(evt1);
    SendNativeKeyEvent(keydown_event);

    MSG msg2 = { NULL, WM_CHAR, (*output)[0], 0 };
    ui::KeyEvent evt2(msg2);
    NativeWebKeyboardEvent char_event(evt2);
    SendNativeKeyEvent(char_event);

    MSG msg3 = { NULL, WM_KEYUP, key_code, 0 };
    ui::KeyEvent evt3(msg3);
    NativeWebKeyboardEvent keyup_event(evt3);
    SendNativeKeyEvent(keyup_event);

    return length;
#elif defined(USE_AURA) && defined(USE_X11)
    // We ignore |layout|, which means we are only testing the layout of the
    // current locale. TODO(mazda): fix this to respect |layout|.
    CHECK(output);
    const int flags = ConvertMockKeyboardModifier(modifiers);

    ui::ScopedXI2Event xevent;
    xevent.InitKeyEvent(ui::ET_KEY_PRESSED,
                        static_cast<ui::KeyboardCode>(key_code),
                        flags);
    ui::KeyEvent event1(xevent);
    NativeWebKeyboardEvent keydown_event(event1);
    SendNativeKeyEvent(keydown_event);

    // X11 doesn't actually have native character events, but give the test
    // what it wants.
    xevent.InitKeyEvent(ui::ET_KEY_PRESSED,
                        static_cast<ui::KeyboardCode>(key_code),
                        flags);
    ui::KeyEvent event2(xevent);
    event2.set_character(
        DomCodeToUsLayoutCharacter(event2.code(), event2.flags()));
    ui::KeyEventTestApi test_event2(&event2);
    test_event2.set_is_char(true);
    NativeWebKeyboardEvent char_event(event2);
    SendNativeKeyEvent(char_event);

    xevent.InitKeyEvent(ui::ET_KEY_RELEASED,
                        static_cast<ui::KeyboardCode>(key_code),
                        flags);
    ui::KeyEvent event3(xevent);
    NativeWebKeyboardEvent keyup_event(event3);
    SendNativeKeyEvent(keyup_event);

    long c = DomCodeToUsLayoutCharacter(
        UsLayoutKeyboardCodeToDomCode(static_cast<ui::KeyboardCode>(key_code)),
        flags);
    output->assign(1, static_cast<base::char16>(c));
    return 1;
#elif defined(USE_OZONE)
    const int flags = ConvertMockKeyboardModifier(modifiers);

    ui::KeyEvent keydown_event(ui::ET_KEY_PRESSED,
                               static_cast<ui::KeyboardCode>(key_code),
                               flags);
    NativeWebKeyboardEvent keydown_web_event(keydown_event);
    SendNativeKeyEvent(keydown_web_event);

    ui::KeyEvent char_event(keydown_event.GetCharacter(),
                            static_cast<ui::KeyboardCode>(key_code),
                            flags);
    NativeWebKeyboardEvent char_web_event(char_event);
    SendNativeKeyEvent(char_web_event);

    ui::KeyEvent keyup_event(ui::ET_KEY_RELEASED,
                             static_cast<ui::KeyboardCode>(key_code),
                             flags);
    NativeWebKeyboardEvent keyup_web_event(keyup_event);
    SendNativeKeyEvent(keyup_web_event);

    long c = DomCodeToUsLayoutCharacter(
        UsLayoutKeyboardCodeToDomCode(static_cast<ui::KeyboardCode>(key_code)),
        flags);
    output->assign(1, static_cast<base::char16>(c));
    return 1;
#else
    NOTIMPLEMENTED();
    return L'\0';
#endif
  }

  void EnablePreferredSizeMode() {
    view()->OnEnablePreferredSizeChangedMode();
  }

  const gfx::Size& GetPreferredSize() {
    view()->CheckPreferredSize();
    return view()->preferred_size_;
  }

  void SetZoomLevel(double level) {
    view()->OnSetZoomLevel(
        PageMsg_SetZoomLevel_Command::USE_CURRENT_TEMPORARY_MODE, level);
  }

  // Closes a view created during the test, i.e. not the |view()|. Checks that
  // the main frame is detached and deleted, and makes sure the view does not
  // leak.
  void CloseRenderView(RenderViewImpl* new_view) {
    new_view->Close();
    EXPECT_FALSE(new_view->GetMainRenderFrame());

    new_view->Release();
  }

 private:
  std::unique_ptr<MockKeyboard> mock_keyboard_;
};

class DevToolsAgentTest : public RenderViewImplTest {
 public:
  void Attach() {
    notifications_ = std::vector<std::string>();
    expecting_pause_ = false;
    std::string host_id = "host_id";
    agent()->OnAttach(host_id, 17);
    agent()->send_protocol_message_callback_for_test_ = base::Bind(
       &DevToolsAgentTest::OnDevToolsMessage, base::Unretained(this));
  }

  void Detach() {
    agent()->send_protocol_message_callback_for_test_.Reset();
    agent()->DetachAllSessions();
  }

  bool IsPaused() {
    return agent()->paused_;
  }

  void DispatchDevToolsMessage(const std::string& method,
                               const std::string& message) {
    agent()->OnDispatchOnInspectorBackend(17, 1, method, message);
  }

  void CloseWhilePaused() {
    EXPECT_TRUE(IsPaused());
    view()->NotifyOnClose();
  }

  void OnDevToolsMessage(
      int, int, const std::string& message, const std::string&) {
    last_message_ = base::WrapUnique(static_cast<base::DictionaryValue*>(
        base::JSONReader::Read(message).release()));
    int id;
    if (!last_message_->GetInteger("id", &id)) {
      std::string notification;
      EXPECT_TRUE(last_message_->GetString("method", &notification));
      notifications_.push_back(notification);

      if (notification == "Debugger.paused" && expecting_pause_) {
        base::ListValue* call_frames;
        EXPECT_TRUE(last_message_->GetList("params.callFrames", &call_frames));
        if (call_frames) {
          EXPECT_EQ(call_frames_count_,
                    static_cast<int>(call_frames->GetSize()));
        }
        expecting_pause_ = false;
        base::ThreadTaskRunnerHandle::Get()->PostTask(
            FROM_HERE,
            base::Bind(&DevToolsAgentTest::DispatchDevToolsMessage,
                       base::Unretained(this),
                       "Debugger.resume",
                       "{\"id\":100,\"method\":\"Debugger.resume\"}"));
      }
    }
  }

  int CountNotifications(const std::string& notification) {
    int result = 0;
    for (const std::string& s : notifications_) {
      if (s == notification)
        ++result;
    }
    return result;
  }

  base::DictionaryValue* LastReceivedMessage() {
    return last_message_.get();
  }

  void ExpectPauseAndResume(int call_frames_count) {
    expecting_pause_ = true;
    call_frames_count_ = call_frames_count;
  }

 private:
  DevToolsAgent* agent() {
    return frame()->devtools_agent();
  }

  std::vector<std::string> notifications_;
  std::unique_ptr<base::DictionaryValue> last_message_;
  int call_frames_count_;
  bool expecting_pause_;
};

class RenderViewImplBlinkSettingsTest : public RenderViewImplTest {
 public:
  virtual void DoSetUp() {
    RenderViewImplTest::SetUp();
  }

  blink::WebSettings* settings() { return view()->webview()->GetSettings(); }

 protected:
  // Blink settings may be specified on the command line, which must
  // be configured before RenderViewImplTest::SetUp runs. Thus we make
  // SetUp() a no-op, and expose RenderViewImplTest::SetUp() via
  // DoSetUp(), to allow tests to perform command line modifications
  // before RenderViewImplTest::SetUp is run. Each test must invoke
  // DoSetUp manually once pre-SetUp configuration is complete.
  void SetUp() override {}
};

class RenderViewImplScaleFactorTest : public RenderViewImplBlinkSettingsTest {
 protected:
  void SetDeviceScaleFactor(float dsf) {
    ResizeParams params;
    params.screen_info.device_scale_factor = dsf;
    params.new_size = gfx::Size(100, 100);
    params.physical_backing_size = gfx::Size(200, 200);
    params.visible_viewport_size = params.new_size;
    params.needs_resize_ack = false;
    view()->OnResize(params);
    ASSERT_EQ(dsf, view()->device_scale_factor_);
  }

  void TestEmulatedSizeDprDsf(int width, int height, float dpr,
                              float compositor_dsf) {
    static base::string16 get_width =
        base::ASCIIToUTF16("Number(window.innerWidth)");
    static base::string16 get_height =
        base::ASCIIToUTF16("Number(window.innerHeight)");
    static base::string16 get_dpr =
        base::ASCIIToUTF16("Number(window.devicePixelRatio * 10)");

    int emulated_width, emulated_height;
    int emulated_dpr;
    blink::WebDeviceEmulationParams params;
    params.view_size.width = width;
    params.view_size.height = height;
    params.device_scale_factor = dpr;
    view()->OnEnableDeviceEmulation(params);
    EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(get_width, &emulated_width));
    EXPECT_EQ(width, emulated_width);
    EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(get_height,
                                                   &emulated_height));
    EXPECT_EQ(height, emulated_height);
    EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(get_dpr, &emulated_dpr));
    EXPECT_EQ(static_cast<int>(dpr * 10), emulated_dpr);
    EXPECT_EQ(compositor_dsf, view()
                                  ->compositor()
                                  ->layer_tree_host()
                                  ->device_scale_factor());
  }
};

// Ensure that the main RenderFrame is deleted and cleared from the RenderView
// after closing it.
TEST_F(RenderViewImplTest, RenderFrameClearedAfterClose) {
  // Create a new main frame RenderFrame so that we don't interfere with the
  // shutdown of frame() in RenderViewTest.TearDown.
  blink::WebURLRequest popup_request(GURL("http://foo.com"));
  blink::WebView* new_web_view = view()->CreateView(
      GetMainFrame(), popup_request, blink::WebWindowFeatures(), "foo",
      blink::kWebNavigationPolicyNewForegroundTab, false);
  RenderViewImpl* new_view = RenderViewImpl::FromWebView(new_web_view);

  // Checks that the frame is deleted properly and cleans up the view.
  CloseRenderView(new_view);
}

// Test that we get form state change notifications when input fields change.
TEST_F(RenderViewImplTest, OnNavStateChanged) {
  view()->set_send_content_state_immediately(true);
  LoadHTML("<input type=\"text\" id=\"elt_text\"></input>");

  // We should NOT have gotten a form state change notification yet.
  EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
      FrameHostMsg_UpdateState::ID));
  render_thread_->sink().ClearMessages();

  // Change the value of the input. We should have gotten an update state
  // notification. We need to spin the message loop to catch this update.
  ExecuteJavaScriptForTests(
      "document.getElementById('elt_text').value = 'foo';");
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(render_thread_->sink().GetUniqueMessageMatching(
      FrameHostMsg_UpdateState::ID));
}

TEST_F(RenderViewImplTest, OnNavigationHttpPost) {
  // An http url will trigger a resource load so cannot be used here.
  CommonNavigationParams common_params;
  StartNavigationParams start_params;
  RequestNavigationParams request_params;
  common_params.url = GURL("data:text/html,<div>Page</div>");
  common_params.navigation_type = FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT;
  common_params.transition = ui::PAGE_TRANSITION_TYPED;
  common_params.method = "POST";

  // Set up post data.
  const char raw_data[] = "post \0\ndata";
  const size_t length = arraysize(raw_data);
  scoped_refptr<ResourceRequestBodyImpl> post_data(new ResourceRequestBodyImpl);
  post_data->AppendBytes(raw_data, length);
  common_params.post_data = post_data;

  frame()->Navigate(common_params, start_params, request_params);
  base::RunLoop().RunUntilIdle();

  const IPC::Message* frame_navigate_msg =
      render_thread_->sink().GetUniqueMessageMatching(
          FrameHostMsg_DidCommitProvisionalLoad::ID);
  EXPECT_TRUE(frame_navigate_msg);

  FrameHostMsg_DidCommitProvisionalLoad::Param host_nav_params;
  FrameHostMsg_DidCommitProvisionalLoad::Read(frame_navigate_msg,
                                              &host_nav_params);
  EXPECT_EQ("POST", std::get<0>(host_nav_params).method);

  // Check post data sent to browser matches
  EXPECT_TRUE(std::get<0>(host_nav_params).page_state.IsValid());
  std::unique_ptr<HistoryEntry> entry =
      PageStateToHistoryEntry(std::get<0>(host_nav_params).page_state);
  blink::WebHTTPBody body = entry->root().HttpBody();
  blink::WebHTTPBody::Element element;
  bool successful = body.ElementAt(0, element);
  EXPECT_TRUE(successful);
  EXPECT_EQ(blink::WebHTTPBody::Element::kTypeData, element.type);
  EXPECT_EQ(length, element.data.size());
  EXPECT_EQ(0, memcmp(raw_data, element.data.Data(), length));
}

#if defined(OS_ANDROID)
TEST_F(RenderViewImplTest, OnNavigationLoadDataWithBaseURL) {
  CommonNavigationParams common_params;
  common_params.url = GURL("data:text/html,");
  common_params.navigation_type = FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT;
  common_params.transition = ui::PAGE_TRANSITION_TYPED;
  common_params.base_url_for_data_url = GURL("about:blank");
  common_params.history_url_for_data_url = GURL("about:blank");
  RequestNavigationParams request_params;
  request_params.data_url_as_string =
      "data:text/html,<html><head><title>Data page</title></head></html>";

  frame()->Navigate(common_params, StartNavigationParams(),
                    request_params);
  const IPC::Message* frame_title_msg = nullptr;
  do {
    base::RunLoop().RunUntilIdle();
    frame_title_msg = render_thread_->sink().GetUniqueMessageMatching(
        FrameHostMsg_UpdateTitle::ID);
  } while (!frame_title_msg);

  // Check post data sent to browser matches.
  FrameHostMsg_UpdateTitle::Param title_params;
  EXPECT_TRUE(FrameHostMsg_UpdateTitle::Read(frame_title_msg, &title_params));
  EXPECT_EQ(base::ASCIIToUTF16("Data page"), std::get<0>(title_params));
}
#endif

TEST_F(RenderViewImplTest, DecideNavigationPolicy) {
  WebUITestWebUIControllerFactory factory;
  WebUIControllerFactory::RegisterFactory(&factory);

  DocumentState state;
  state.set_navigation_state(NavigationStateImpl::CreateContentInitiated());

  // Navigations to normal HTTP URLs can be handled locally.
  blink::WebURLRequest request(GURL("http://foo.com"));
  request.SetFetchRequestMode(blink::WebURLRequest::kFetchRequestModeNavigate);
  request.SetFetchCredentialsMode(
      blink::WebURLRequest::kFetchCredentialsModeInclude);
  request.SetFetchRedirectMode(blink::WebURLRequest::kFetchRedirectModeManual);
  request.SetFrameType(blink::WebURLRequest::kFrameTypeTopLevel);
  request.SetRequestContext(blink::WebURLRequest::kRequestContextInternal);
  blink::WebFrameClient::NavigationPolicyInfo policy_info(request);
  policy_info.navigation_type = blink::kWebNavigationTypeLinkClicked;
  policy_info.default_policy = blink::kWebNavigationPolicyCurrentTab;
  blink::WebNavigationPolicy policy =
      frame()->DecidePolicyForNavigation(policy_info);
  if (!IsBrowserSideNavigationEnabled()) {
    EXPECT_EQ(blink::kWebNavigationPolicyCurrentTab, policy);
  } else {
    // If this is a renderer-initiated navigation that just begun, it should
    // stop and be sent to the browser.
    EXPECT_EQ(blink::kWebNavigationPolicyHandledByClient, policy);

    // If this a navigation that is ready to commit, it should be handled
    // locally.
    request.SetCheckForBrowserSideNavigation(false);
    policy = frame()->DecidePolicyForNavigation(policy_info);
    EXPECT_EQ(blink::kWebNavigationPolicyCurrentTab, policy);
  }

  // Verify that form posts to WebUI URLs will be sent to the browser process.
  blink::WebURLRequest form_request(GURL("chrome://foo"));
  blink::WebFrameClient::NavigationPolicyInfo form_policy_info(form_request);
  form_policy_info.navigation_type = blink::kWebNavigationTypeFormSubmitted;
  form_policy_info.default_policy = blink::kWebNavigationPolicyCurrentTab;
  form_request.SetHTTPMethod("POST");
  policy = frame()->DecidePolicyForNavigation(form_policy_info);
  EXPECT_EQ(blink::kWebNavigationPolicyIgnore, policy);

  // Verify that popup links to WebUI URLs also are sent to browser.
  blink::WebURLRequest popup_request(GURL("chrome://foo"));
  blink::WebFrameClient::NavigationPolicyInfo popup_policy_info(popup_request);
  popup_policy_info.navigation_type = blink::kWebNavigationTypeLinkClicked;
  popup_policy_info.default_policy =
      blink::kWebNavigationPolicyNewForegroundTab;
  policy = frame()->DecidePolicyForNavigation(popup_policy_info);
  EXPECT_EQ(blink::kWebNavigationPolicyIgnore, policy);
}

TEST_F(RenderViewImplTest, DecideNavigationPolicyHandlesAllTopLevel) {
  DocumentState state;
  state.set_navigation_state(NavigationStateImpl::CreateContentInitiated());

  RendererPreferences prefs = view()->renderer_preferences();
  prefs.browser_handles_all_top_level_requests = true;
  view()->OnSetRendererPrefs(prefs);

  const blink::WebNavigationType kNavTypes[] = {
      blink::kWebNavigationTypeLinkClicked,
      blink::kWebNavigationTypeFormSubmitted,
      blink::kWebNavigationTypeBackForward,
      blink::kWebNavigationTypeReload,
      blink::kWebNavigationTypeFormResubmitted,
      blink::kWebNavigationTypeOther,
  };

  blink::WebURLRequest request(GURL("http://foo.com"));
  blink::WebFrameClient::NavigationPolicyInfo policy_info(request);
  policy_info.default_policy = blink::kWebNavigationPolicyCurrentTab;

  for (size_t i = 0; i < arraysize(kNavTypes); ++i) {
    policy_info.navigation_type = kNavTypes[i];

    blink::WebNavigationPolicy policy =
        frame()->DecidePolicyForNavigation(policy_info);
    EXPECT_EQ(blink::kWebNavigationPolicyIgnore, policy);
  }
}

TEST_F(RenderViewImplTest, DecideNavigationPolicyForWebUI) {
  // Enable bindings to simulate a WebUI view.
  view()->GetMainRenderFrame()->AllowBindings(BINDINGS_POLICY_WEB_UI);

  DocumentState state;
  state.set_navigation_state(NavigationStateImpl::CreateContentInitiated());

  // Navigations to normal HTTP URLs will be sent to browser process.
  blink::WebURLRequest request(GURL("http://foo.com"));
  blink::WebFrameClient::NavigationPolicyInfo policy_info(request);
  policy_info.navigation_type = blink::kWebNavigationTypeLinkClicked;
  policy_info.default_policy = blink::kWebNavigationPolicyCurrentTab;

  blink::WebNavigationPolicy policy =
      frame()->DecidePolicyForNavigation(policy_info);
  EXPECT_EQ(blink::kWebNavigationPolicyIgnore, policy);

  // Navigations to WebUI URLs will also be sent to browser process.
  blink::WebURLRequest webui_request(GURL("chrome://foo"));
  blink::WebFrameClient::NavigationPolicyInfo webui_policy_info(webui_request);
  webui_policy_info.navigation_type = blink::kWebNavigationTypeLinkClicked;
  webui_policy_info.default_policy = blink::kWebNavigationPolicyCurrentTab;
  policy = frame()->DecidePolicyForNavigation(webui_policy_info);
  EXPECT_EQ(blink::kWebNavigationPolicyIgnore, policy);

  // Verify that form posts to data URLs will be sent to the browser process.
  blink::WebURLRequest data_request(GURL("data:text/html,foo"));
  blink::WebFrameClient::NavigationPolicyInfo data_policy_info(data_request);
  data_policy_info.navigation_type = blink::kWebNavigationTypeFormSubmitted;
  data_policy_info.default_policy = blink::kWebNavigationPolicyCurrentTab;
  data_request.SetHTTPMethod("POST");
  policy = frame()->DecidePolicyForNavigation(data_policy_info);
  EXPECT_EQ(blink::kWebNavigationPolicyIgnore, policy);

  // Verify that a popup that creates a view first and then navigates to a
  // normal HTTP URL will be sent to the browser process, even though the
  // new view does not have any enabled_bindings_.
  blink::WebURLRequest popup_request(GURL("http://foo.com"));
  blink::WebView* new_web_view = view()->CreateView(
      GetMainFrame(), popup_request, blink::WebWindowFeatures(), "foo",
      blink::kWebNavigationPolicyNewForegroundTab, false);
  RenderViewImpl* new_view = RenderViewImpl::FromWebView(new_web_view);
  blink::WebFrameClient::NavigationPolicyInfo popup_policy_info(popup_request);
  popup_policy_info.navigation_type = blink::kWebNavigationTypeLinkClicked;
  popup_policy_info.default_policy =
      blink::kWebNavigationPolicyNewForegroundTab;
  policy = static_cast<RenderFrameImpl*>(new_view->GetMainRenderFrame())
               ->DecidePolicyForNavigation(popup_policy_info);
  EXPECT_EQ(blink::kWebNavigationPolicyIgnore, policy);

  CloseRenderView(new_view);
}

// Verify that security origins are replicated properly to RenderFrameProxies
// when swapping out.
TEST_F(RenderViewImplTest, OriginReplicationForSwapOut) {
  // This test should only run with --site-per-process, since origin
  // replication only happens in that mode.
  if (!AreAllSitesIsolatedForTesting())
    return;

  LoadHTML(
      "Hello <iframe src='data:text/html,frame 1'></iframe>"
      "<iframe src='data:text/html,frame 2'></iframe>");
  WebFrame* web_frame = frame()->GetWebFrame();
  TestRenderFrame* child_frame = static_cast<TestRenderFrame*>(
      RenderFrame::FromWebFrame(web_frame->FirstChild()));

  // Swap the child frame out and pass a replicated origin to be set for
  // WebRemoteFrame.
  content::FrameReplicationState replication_state =
      ReconstructReplicationStateForTesting(child_frame);
  replication_state.origin = url::Origin(GURL("http://foo.com"));
  child_frame->SwapOut(kProxyRoutingId, true, replication_state);

  // The child frame should now be a WebRemoteFrame.
  EXPECT_TRUE(web_frame->FirstChild()->IsWebRemoteFrame());

  // Expect the origin to be updated properly.
  blink::WebSecurityOrigin origin =
      web_frame->FirstChild()->GetSecurityOrigin();
  EXPECT_EQ(origin.ToString(),
            WebString::FromUTF8(replication_state.origin.Serialize()));

  // Now, swap out the second frame using a unique origin and verify that it is
  // replicated correctly.
  replication_state.origin = url::Origin();
  TestRenderFrame* child_frame2 = static_cast<TestRenderFrame*>(
      RenderFrame::FromWebFrame(web_frame->FirstChild()->NextSibling()));
  child_frame2->SwapOut(kProxyRoutingId + 1, true, replication_state);
  EXPECT_TRUE(web_frame->FirstChild()->NextSibling()->IsWebRemoteFrame());
  EXPECT_TRUE(
      web_frame->FirstChild()->NextSibling()->GetSecurityOrigin().IsUnique());
}

// Test that when a parent detaches a remote child after the provisional
// RenderFrame is created but before it is navigated, the RenderFrame is
// destroyed along with the proxy.  This protects against races in
// https://crbug.com/526304 and https://crbug.com/568676.
TEST_F(RenderViewImplTest, DetachingProxyAlsoDestroysProvisionalFrame) {
  // This test should only run with --site-per-process.
  if (!AreAllSitesIsolatedForTesting())
    return;

  LoadHTML("Hello <iframe src='data:text/html,frame 1'></iframe>");
  WebFrame* web_frame = frame()->GetWebFrame();
  TestRenderFrame* child_frame = static_cast<TestRenderFrame*>(
      RenderFrame::FromWebFrame(web_frame->FirstChild()));

  // Swap the child frame out.
  FrameReplicationState replication_state =
      ReconstructReplicationStateForTesting(child_frame);
  child_frame->SwapOut(kProxyRoutingId, true, replication_state);
  EXPECT_TRUE(web_frame->FirstChild()->IsWebRemoteFrame());

  // Do the first step of a remote-to-local transition for the child proxy,
  // which is to create a provisional local frame.
  int routing_id = kProxyRoutingId + 1;
  mojom::CreateFrameWidgetParams widget_params;
  widget_params.routing_id = MSG_ROUTING_NONE;
  widget_params.hidden = false;
  RenderFrameImpl::CreateFrame(routing_id, kProxyRoutingId, MSG_ROUTING_NONE,
                               frame()->GetRoutingID(), MSG_ROUTING_NONE,
                               replication_state, nullptr, widget_params,
                               FrameOwnerProperties());
  {
    TestRenderFrame* provisional_frame = static_cast<TestRenderFrame*>(
        RenderFrameImpl::FromRoutingID(routing_id));
    EXPECT_TRUE(provisional_frame);
  }

  // Detach the child frame (currently remote) in the main frame.
  ExecuteJavaScriptForTests(
      "document.body.removeChild(document.querySelector('iframe'));");
  RenderFrameProxy* child_proxy =
      RenderFrameProxy::FromRoutingID(kProxyRoutingId);
  EXPECT_FALSE(child_proxy);

  // The provisional frame should have been deleted along with the proxy, and
  // thus any subsequent messages (such as OnNavigate) already in flight for it
  // should be dropped.
  {
    TestRenderFrame* provisional_frame = static_cast<TestRenderFrame*>(
        RenderFrameImpl::FromRoutingID(routing_id));
    EXPECT_FALSE(provisional_frame);
  }
}

// Verify that the renderer process doesn't crash when device scale factor
// changes after a cross-process navigation has commited.
// See https://crbug.com/571603.
TEST_F(RenderViewImplTest, SetZoomLevelAfterCrossProcessNavigation) {
  // This test should only run with out-of-process iframes enabled.
  if (!SiteIsolationPolicy::AreCrossProcessFramesPossible())
    return;

  // The bug reproduces if zoom is used for devices scale factor.
  base::CommandLine::ForCurrentProcess()->AppendSwitch(
      switches::kEnableUseZoomForDSF);

  LoadHTML("Hello world!");

  // Swap the main frame out after which it should become a WebRemoteFrame.
  TestRenderFrame* main_frame =
      static_cast<TestRenderFrame*>(view()->GetMainRenderFrame());
  main_frame->SwapOut(kProxyRoutingId, true,
                      ReconstructReplicationStateForTesting(main_frame));
  EXPECT_TRUE(view()->webview()->MainFrame()->IsWebRemoteFrame());

  // This should not cause a crash.
  view()->OnDeviceScaleFactorChanged();
}

// Test that we get the correct UpdateState message when we go back twice
// quickly without committing.  Regression test for http://crbug.com/58082.
// Disabled: http://crbug.com/157357 .
TEST_F(RenderViewImplTest,  DISABLED_LastCommittedUpdateState) {
  // Load page A.
  LoadHTML("<div>Page A</div>");

  // Load page B, which will trigger an UpdateState message for page A.
  LoadHTML("<div>Page B</div>");

  // Check for a valid UpdateState message for page A.
  base::RunLoop().RunUntilIdle();
  const IPC::Message* msg_A = render_thread_->sink().GetUniqueMessageMatching(
      FrameHostMsg_UpdateState::ID);
  ASSERT_TRUE(msg_A);
  FrameHostMsg_UpdateState::Param param;
  FrameHostMsg_UpdateState::Read(msg_A, &param);
  PageState state_A = std::get<0>(param);
  render_thread_->sink().ClearMessages();

  // Load page C, which will trigger an UpdateState message for page B.
  LoadHTML("<div>Page C</div>");

  // Check for a valid UpdateState for page B.
  base::RunLoop().RunUntilIdle();
  const IPC::Message* msg_B = render_thread_->sink().GetUniqueMessageMatching(
      FrameHostMsg_UpdateState::ID);
  ASSERT_TRUE(msg_B);
  FrameHostMsg_UpdateState::Read(msg_B, &param);
  PageState state_B = std::get<0>(param);
  EXPECT_NE(state_A, state_B);
  render_thread_->sink().ClearMessages();

  // Load page D, which will trigger an UpdateState message for page C.
  LoadHTML("<div>Page D</div>");

  // Check for a valid UpdateState for page C.
  base::RunLoop().RunUntilIdle();
  const IPC::Message* msg_C = render_thread_->sink().GetUniqueMessageMatching(
      FrameHostMsg_UpdateState::ID);
  ASSERT_TRUE(msg_C);
  FrameHostMsg_UpdateState::Read(msg_C, &param);
  PageState state_C = std::get<0>(param);
  EXPECT_NE(state_B, state_C);
  render_thread_->sink().ClearMessages();

  // Go back to C and commit, preparing for our real test.
  CommonNavigationParams common_params_C;
  RequestNavigationParams request_params_C;
  common_params_C.navigation_type =
      FrameMsg_Navigate_Type::HISTORY_DIFFERENT_DOCUMENT;
  common_params_C.transition = ui::PAGE_TRANSITION_FORWARD_BACK;
  request_params_C.current_history_list_length = 4;
  request_params_C.current_history_list_offset = 3;
  request_params_C.pending_history_list_offset = 2;
  request_params_C.nav_entry_id = 3;
  request_params_C.page_state = state_C;
  frame()->Navigate(common_params_C, StartNavigationParams(), request_params_C);
  base::RunLoop().RunUntilIdle();
  render_thread_->sink().ClearMessages();

  // Go back twice quickly, such that page B does not have a chance to commit.
  // This leads to two changes to the back/forward list but only one change to
  // the RenderView's page ID.

  // Back to page B without committing.
  CommonNavigationParams common_params_B;
  RequestNavigationParams request_params_B;
  common_params_B.navigation_type =
      FrameMsg_Navigate_Type::HISTORY_DIFFERENT_DOCUMENT;
  common_params_B.transition = ui::PAGE_TRANSITION_FORWARD_BACK;
  request_params_B.current_history_list_length = 4;
  request_params_B.current_history_list_offset = 2;
  request_params_B.pending_history_list_offset = 1;
  request_params_B.nav_entry_id = 2;
  request_params_B.page_state = state_B;
  frame()->Navigate(common_params_B, StartNavigationParams(), request_params_B);

  // Back to page A and commit.
  CommonNavigationParams common_params;
  RequestNavigationParams request_params;
  common_params.navigation_type =
      FrameMsg_Navigate_Type::HISTORY_DIFFERENT_DOCUMENT;
  common_params.transition = ui::PAGE_TRANSITION_FORWARD_BACK;
  request_params.current_history_list_length = 4;
  request_params.current_history_list_offset = 2;
  request_params.pending_history_list_offset = 0;
  request_params.nav_entry_id = 1;
  request_params.page_state = state_A;
  frame()->Navigate(common_params, StartNavigationParams(), request_params);
  base::RunLoop().RunUntilIdle();

  // Now ensure that the UpdateState message we receive is consistent
  // and represents page C in state.
  const IPC::Message* msg = render_thread_->sink().GetUniqueMessageMatching(
      FrameHostMsg_UpdateState::ID);
  ASSERT_TRUE(msg);
  FrameHostMsg_UpdateState::Read(msg, &param);
  PageState state = std::get<0>(param);
  EXPECT_NE(state_A, state);
  EXPECT_NE(state_B, state);
  EXPECT_EQ(state_C, state);
}

// Test that our IME backend sends a notification message when the input focus
// changes.
TEST_F(RenderViewImplTest, OnImeTypeChanged) {
  // Load an HTML page consisting of two input fields.
  LoadHTML("<html>"
           "<head>"
           "</head>"
           "<body>"
           "<input id=\"test1\" type=\"text\" value=\"some text\"></input>"
           "<input id=\"test2\" type=\"password\"></input>"
           "<input id=\"test3\" type=\"text\" inputmode=\"verbatim\"></input>"
           "<input id=\"test4\" type=\"text\" inputmode=\"latin\"></input>"
           "<input id=\"test5\" type=\"text\" inputmode=\"latin-name\"></input>"
           "<input id=\"test6\" type=\"text\" inputmode=\"latin-prose\">"
               "</input>"
           "<input id=\"test7\" type=\"text\" inputmode=\"full-width-latin\">"
               "</input>"
           "<input id=\"test8\" type=\"text\" inputmode=\"kana\"></input>"
           "<input id=\"test9\" type=\"text\" inputmode=\"katakana\"></input>"
           "<input id=\"test10\" type=\"text\" inputmode=\"numeric\"></input>"
           "<input id=\"test11\" type=\"text\" inputmode=\"tel\"></input>"
           "<input id=\"test12\" type=\"text\" inputmode=\"email\"></input>"
           "<input id=\"test13\" type=\"text\" inputmode=\"url\"></input>"
           "<input id=\"test14\" type=\"text\" inputmode=\"unknown\"></input>"
           "<input id=\"test15\" type=\"text\" inputmode=\"verbatim\"></input>"
           "</body>"
           "</html>");
  render_thread_->sink().ClearMessages();

  struct InputModeTestCase {
    const char* input_id;
    ui::TextInputMode expected_mode;
  };
  static const InputModeTestCase kInputModeTestCases[] = {
     {"test1", ui::TEXT_INPUT_MODE_DEFAULT},
     {"test3", ui::TEXT_INPUT_MODE_VERBATIM},
     {"test4", ui::TEXT_INPUT_MODE_LATIN},
     {"test5", ui::TEXT_INPUT_MODE_LATIN_NAME},
     {"test6", ui::TEXT_INPUT_MODE_LATIN_PROSE},
     {"test7", ui::TEXT_INPUT_MODE_FULL_WIDTH_LATIN},
     {"test8", ui::TEXT_INPUT_MODE_KANA},
     {"test9", ui::TEXT_INPUT_MODE_KATAKANA},
     {"test10", ui::TEXT_INPUT_MODE_NUMERIC},
     {"test11", ui::TEXT_INPUT_MODE_TEL},
     {"test12", ui::TEXT_INPUT_MODE_EMAIL},
     {"test13", ui::TEXT_INPUT_MODE_URL},
     {"test14", ui::TEXT_INPUT_MODE_DEFAULT},
     {"test15", ui::TEXT_INPUT_MODE_VERBATIM},
  };

  const int kRepeatCount = 10;
  for (int i = 0; i < kRepeatCount; i++) {
    // Move the input focus to the first <input> element, where we should
    // activate IMEs.
    ExecuteJavaScriptForTests("document.getElementById('test1').focus();");
    base::RunLoop().RunUntilIdle();
    render_thread_->sink().ClearMessages();

    // Update the IME status and verify if our IME backend sends an IPC message
    // to activate IMEs.
    view()->UpdateTextInputState();
    const IPC::Message* msg = render_thread_->sink().GetMessageAt(0);
    EXPECT_TRUE(msg != NULL);
    EXPECT_EQ(ViewHostMsg_TextInputStateChanged::ID, msg->type());
    ViewHostMsg_TextInputStateChanged::Param params;
    ViewHostMsg_TextInputStateChanged::Read(msg, &params);
    TextInputState p = std::get<0>(params);
    ui::TextInputType type = p.type;
    ui::TextInputMode input_mode = p.mode;
    bool can_compose_inline = p.can_compose_inline;
    EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, type);
    EXPECT_EQ(true, can_compose_inline);

    // Move the input focus to the second <input> element, where we should
    // de-activate IMEs.
    ExecuteJavaScriptForTests("document.getElementById('test2').focus();");
    base::RunLoop().RunUntilIdle();
    render_thread_->sink().ClearMessages();

    // Update the IME status and verify if our IME backend sends an IPC message
    // to de-activate IMEs.
    view()->UpdateTextInputState();
    msg = render_thread_->sink().GetMessageAt(0);
    EXPECT_TRUE(msg != NULL);
    EXPECT_EQ(ViewHostMsg_TextInputStateChanged::ID, msg->type());
    ViewHostMsg_TextInputStateChanged::Read(msg, &params);
    p = std::get<0>(params);
    type = p.type;
    input_mode = p.mode;
    EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, type);

    for (size_t i = 0; i < arraysize(kInputModeTestCases); i++) {
      const InputModeTestCase* test_case = &kInputModeTestCases[i];
      std::string javascript =
          base::StringPrintf("document.getElementById('%s').focus();",
                             test_case->input_id);
      // Move the input focus to the target <input> element, where we should
      // activate IMEs.
      ExecuteJavaScriptAndReturnIntValue(base::ASCIIToUTF16(javascript), NULL);
      base::RunLoop().RunUntilIdle();
      render_thread_->sink().ClearMessages();

      // Update the IME status and verify if our IME backend sends an IPC
      // message to activate IMEs.
      view()->UpdateTextInputState();
      base::RunLoop().RunUntilIdle();
      const IPC::Message* msg = render_thread_->sink().GetMessageAt(0);
      EXPECT_TRUE(msg != NULL);
      EXPECT_EQ(ViewHostMsg_TextInputStateChanged::ID, msg->type());
      ViewHostMsg_TextInputStateChanged::Read(msg, &params);
      p = std::get<0>(params);
      type = p.type;
      input_mode = p.mode;
      EXPECT_EQ(test_case->expected_mode, input_mode);
    }
  }
}

// Test that our IME backend can compose CJK words.
// Our IME front-end sends many platform-independent messages to the IME backend
// while it composes CJK words. This test sends the minimal messages captured
// on my local environment directly to the IME backend to verify if the backend
// can compose CJK words without any problems.
// This test uses an array of command sets because an IME composotion does not
// only depends on IME events, but also depends on window events, e.g. moving
// the window focus while composing a CJK text. To handle such complicated
// cases, this test should not only call IME-related functions in the
// RenderWidget class, but also call some RenderWidget members, e.g.
// ExecuteJavaScriptForTests(), RenderWidget::OnSetFocus(), etc.
TEST_F(RenderViewImplTest, ImeComposition) {
  enum ImeCommand {
    IME_INITIALIZE,
    IME_SETINPUTMODE,
    IME_SETFOCUS,
    IME_SETCOMPOSITION,
    IME_COMMITTEXT,
    IME_FINISHCOMPOSINGTEXT,
    IME_CANCELCOMPOSITION
  };
  struct ImeMessage {
    ImeCommand command;
    bool enable;
    int selection_start;
    int selection_end;
    const wchar_t* ime_string;
    const wchar_t* result;
  };
  static const ImeMessage kImeMessages[] = {
      // Scenario 1: input a Chinese word with Microsoft IME (on Vista).
      {IME_INITIALIZE, true, 0, 0, NULL, NULL},
      {IME_SETINPUTMODE, true, 0, 0, NULL, NULL},
      {IME_SETFOCUS, true, 0, 0, NULL, NULL},
      {IME_SETCOMPOSITION, false, 1, 1, L"n", L"n"},
      {IME_SETCOMPOSITION, false, 2, 2, L"ni", L"ni"},
      {IME_SETCOMPOSITION, false, 3, 3, L"nih", L"nih"},
      {IME_SETCOMPOSITION, false, 4, 4, L"niha", L"niha"},
      {IME_SETCOMPOSITION, false, 5, 5, L"nihao", L"nihao"},
      {IME_COMMITTEXT, false, -1, -1, L"\x4F60\x597D", L"\x4F60\x597D"},
      // Scenario 2: input a Japanese word with Microsoft IME (on Vista).
      {IME_INITIALIZE, true, 0, 0, NULL, NULL},
      {IME_SETINPUTMODE, true, 0, 0, NULL, NULL},
      {IME_SETFOCUS, true, 0, 0, NULL, NULL},
      {IME_SETCOMPOSITION, false, 0, 1, L"\xFF4B", L"\xFF4B"},
      {IME_SETCOMPOSITION, false, 0, 1, L"\x304B", L"\x304B"},
      {IME_SETCOMPOSITION, false, 0, 2, L"\x304B\xFF4E", L"\x304B\xFF4E"},
      {IME_SETCOMPOSITION, false, 0, 3, L"\x304B\x3093\xFF4A",
       L"\x304B\x3093\xFF4A"},
      {IME_SETCOMPOSITION, false, 0, 3, L"\x304B\x3093\x3058",
       L"\x304B\x3093\x3058"},
      {IME_SETCOMPOSITION, false, 0, 2, L"\x611F\x3058", L"\x611F\x3058"},
      {IME_SETCOMPOSITION, false, 0, 2, L"\x6F22\x5B57", L"\x6F22\x5B57"},
      {IME_FINISHCOMPOSINGTEXT, false, -1, -1, L"", L"\x6F22\x5B57"},
      {IME_CANCELCOMPOSITION, false, -1, -1, L"", L"\x6F22\x5B57"},
      // Scenario 3: input a Korean word with Microsot IME (on Vista).
      {IME_INITIALIZE, true, 0, 0, NULL, NULL},
      {IME_SETINPUTMODE, true, 0, 0, NULL, NULL},
      {IME_SETFOCUS, true, 0, 0, NULL, NULL},
      {IME_SETCOMPOSITION, false, 0, 1, L"\x3147", L"\x3147"},
      {IME_SETCOMPOSITION, false, 0, 1, L"\xC544", L"\xC544"},
      {IME_SETCOMPOSITION, false, 0, 1, L"\xC548", L"\xC548"},
      {IME_FINISHCOMPOSINGTEXT, false, -1, -1, L"", L"\xC548"},
      {IME_SETCOMPOSITION, false, 0, 1, L"\x3134", L"\xC548\x3134"},
      {IME_SETCOMPOSITION, false, 0, 1, L"\xB140", L"\xC548\xB140"},
      {IME_SETCOMPOSITION, false, 0, 1, L"\xB155", L"\xC548\xB155"},
      {IME_CANCELCOMPOSITION, false, -1, -1, L"", L"\xC548"},
      {IME_SETCOMPOSITION, false, 0, 1, L"\xB155", L"\xC548\xB155"},
      {IME_FINISHCOMPOSINGTEXT, false, -1, -1, L"", L"\xC548\xB155"},
  };

  for (size_t i = 0; i < arraysize(kImeMessages); i++) {
    const ImeMessage* ime_message = &kImeMessages[i];
    switch (ime_message->command) {
      case IME_INITIALIZE:
        // Load an HTML page consisting of a content-editable <div> element,
        // and move the input focus to the <div> element, where we can use
        // IMEs.
        LoadHTML("<html>"
                "<head>"
                "</head>"
                "<body>"
                "<div id=\"test1\" contenteditable=\"true\"></div>"
                "</body>"
                "</html>");
        ExecuteJavaScriptForTests("document.getElementById('test1').focus();");
        break;

      case IME_SETINPUTMODE:
        break;

      case IME_SETFOCUS:
        // Update the window focus.
        view()->OnSetFocus(ime_message->enable);
        break;

      case IME_SETCOMPOSITION:
        view()->OnImeSetComposition(
            base::WideToUTF16(ime_message->ime_string),
            std::vector<blink::WebCompositionUnderline>(),
            gfx::Range::InvalidRange(),
            ime_message->selection_start,
            ime_message->selection_end);
        break;

      case IME_COMMITTEXT:
        view()->OnImeCommitText(base::WideToUTF16(ime_message->ime_string),
                                std::vector<blink::WebCompositionUnderline>(),
                                gfx::Range::InvalidRange(), 0);
        break;

      case IME_FINISHCOMPOSINGTEXT:
        view()->OnImeFinishComposingText(false);
        break;

      case IME_CANCELCOMPOSITION:
        view()->OnImeSetComposition(
            base::string16(),
            std::vector<blink::WebCompositionUnderline>(),
            gfx::Range::InvalidRange(),
            0, 0);
        break;
    }

    // Update the status of our IME back-end.
    // TODO(hbono): we should verify messages to be sent from the back-end.
    view()->UpdateTextInputState();
    base::RunLoop().RunUntilIdle();
    render_thread_->sink().ClearMessages();

    if (ime_message->result) {
      // Retrieve the content of this page and compare it with the expected
      // result.
      const int kMaxOutputCharacters = 128;
      base::string16 output = WebFrameContentDumper::DumpWebViewAsText(
                                  view()->GetWebView(), kMaxOutputCharacters)
                                  .Utf16();
      EXPECT_EQ(base::WideToUTF16(ime_message->result), output);
    }
  }
}

// Test that the RenderView::OnSetTextDirection() function can change the text
// direction of the selected input element.
TEST_F(RenderViewImplTest, OnSetTextDirection) {
  // Load an HTML page consisting of a <textarea> element and a <div> element.
  // This test changes the text direction of the <textarea> element, and
  // writes the values of its 'dir' attribute and its 'direction' property to
  // verify that the text direction is changed.
  LoadHTML("<html>"
           "<head>"
           "</head>"
           "<body>"
           "<textarea id=\"test\"></textarea>"
           "<div id=\"result\" contenteditable=\"true\"></div>"
           "</body>"
           "</html>");
  render_thread_->sink().ClearMessages();

  static const struct {
    WebTextDirection direction;
    const wchar_t* expected_result;
  } kTextDirection[] = {
      {blink::kWebTextDirectionRightToLeft,
       L"\x000A"
       L"rtl,rtl"},
      {blink::kWebTextDirectionLeftToRight,
       L"\x000A"
       L"ltr,ltr"},
  };
  for (size_t i = 0; i < arraysize(kTextDirection); ++i) {
    // Set the text direction of the <textarea> element.
    ExecuteJavaScriptForTests("document.getElementById('test').focus();");
    view()->OnSetTextDirection(kTextDirection[i].direction);

    // Write the values of its DOM 'dir' attribute and its CSS 'direction'
    // property to the <div> element.
    ExecuteJavaScriptForTests(
        "var result = document.getElementById('result');"
        "var node = document.getElementById('test');"
        "var style = getComputedStyle(node, null);"
        "result.innerText ="
        "    node.getAttribute('dir') + ',' +"
        "    style.getPropertyValue('direction');");

    // Copy the document content to std::wstring and compare with the
    // expected result.
    const int kMaxOutputCharacters = 16;
    base::string16 output = WebFrameContentDumper::DumpWebViewAsText(
                                view()->GetWebView(), kMaxOutputCharacters)
                                .Utf16();
    EXPECT_EQ(base::WideToUTF16(kTextDirection[i].expected_result), output);
  }
}

// Crashy, http://crbug.com/53247.
TEST_F(RenderViewImplTest, DISABLED_DidFailProvisionalLoadWithErrorForError) {
  GetMainFrame()->EnableViewSourceMode(true);
  WebURLError error;
  error.domain = WebString::FromUTF8(net::kErrorDomain);
  error.reason = net::ERR_FILE_NOT_FOUND;
  error.unreachable_url = GURL("http://foo");
  WebLocalFrame* web_frame = GetMainFrame();

  // Start a load that will reach provisional state synchronously,
  // but won't complete synchronously.
  CommonNavigationParams common_params;
  common_params.navigation_type = FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT;
  common_params.url = GURL("data:text/html,test data");
  frame()->Navigate(common_params, StartNavigationParams(),
                    RequestNavigationParams());

  // An error occurred.
  view()->GetMainRenderFrame()->DidFailProvisionalLoad(
      error, blink::kWebStandardCommit);
  // Frame should exit view-source mode.
  EXPECT_FALSE(web_frame->IsViewSourceModeEnabled());
}

TEST_F(RenderViewImplTest, DidFailProvisionalLoadWithErrorForCancellation) {
  GetMainFrame()->EnableViewSourceMode(true);
  WebURLError error;
  error.domain = WebString::FromUTF8(net::kErrorDomain);
  error.reason = net::ERR_ABORTED;
  error.unreachable_url = GURL("http://foo");
  WebLocalFrame* web_frame = GetMainFrame();

  // Start a load that will reach provisional state synchronously,
  // but won't complete synchronously.
  CommonNavigationParams common_params;
  common_params.navigation_type = FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT;
  common_params.url = GURL("data:text/html,test data");
  frame()->Navigate(common_params, StartNavigationParams(),
                    RequestNavigationParams());

  // A cancellation occurred.
  view()->GetMainRenderFrame()->DidFailProvisionalLoad(
      error, blink::kWebStandardCommit);
  // Frame should stay in view-source mode.
  EXPECT_TRUE(web_frame->IsViewSourceModeEnabled());
}

// Regression test for http://crbug.com/41562
TEST_F(RenderViewImplTest, UpdateTargetURLWithInvalidURL) {
  const GURL invalid_gurl("http://");
  view()->SetMouseOverURL(blink::WebURL(invalid_gurl));
  EXPECT_EQ(invalid_gurl, view()->target_url_);
}

TEST_F(RenderViewImplTest, SetHistoryLengthAndOffset) {
  // No history to merge; one committed page.
  view()->OnSetHistoryOffsetAndLength(0, 1);
  EXPECT_EQ(1, view()->history_list_length_);
  EXPECT_EQ(0, view()->history_list_offset_);

  // History of length 1 to merge; one committed page.
  view()->OnSetHistoryOffsetAndLength(1, 2);
  EXPECT_EQ(2, view()->history_list_length_);
  EXPECT_EQ(1, view()->history_list_offset_);
}

TEST_F(RenderViewImplTest, ContextMenu) {
  LoadHTML("<div>Page A</div>");

  // Create a right click in the center of the iframe. (I'm hoping this will
  // make this a bit more robust in case of some other formatting or other bug.)
  WebMouseEvent mouse_event(WebInputEvent::kMouseDown,
                            WebInputEvent::kNoModifiers,
                            ui::EventTimeStampToSeconds(ui::EventTimeForNow()));
  mouse_event.button = WebMouseEvent::Button::kRight;
  mouse_event.SetPositionInWidget(250, 250);
  mouse_event.SetPositionInScreen(250, 250);

  SendWebMouseEvent(mouse_event);

  // Now simulate the corresponding up event which should display the menu
  mouse_event.SetType(WebInputEvent::kMouseUp);
  SendWebMouseEvent(mouse_event);

  EXPECT_TRUE(render_thread_->sink().GetUniqueMessageMatching(
      FrameHostMsg_ContextMenu::ID));
}

TEST_F(RenderViewImplTest, TestBackForward) {
  LoadHTML("<div id=pagename>Page A</div>");
  PageState page_a_state = GetCurrentPageState();
  int was_page_a = -1;
  base::string16 check_page_a =
      base::ASCIIToUTF16(
          "Number(document.getElementById('pagename').innerHTML == 'Page A')");
  EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_a, &was_page_a));
  EXPECT_EQ(1, was_page_a);

  LoadHTML("<div id=pagename>Page B</div>");
  int was_page_b = -1;
  base::string16 check_page_b =
      base::ASCIIToUTF16(
          "Number(document.getElementById('pagename').innerHTML == 'Page B')");
  EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_b, &was_page_b));
  EXPECT_EQ(1, was_page_b);

  PageState back_state = GetCurrentPageState();

  LoadHTML("<div id=pagename>Page C</div>");
  int was_page_c = -1;
  base::string16 check_page_c =
      base::ASCIIToUTF16(
          "Number(document.getElementById('pagename').innerHTML == 'Page C')");
  EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_c, &was_page_c));
  EXPECT_EQ(1, was_page_c);

  PageState forward_state = GetCurrentPageState();

  // Go back.
  GoBack(GURL("data:text/html;charset=utf-8,<div id=pagename>Page B</div>"),
         back_state);

  EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_b, &was_page_b));
  EXPECT_EQ(1, was_page_b);
  PageState back_state2 = GetCurrentPageState();

  // Go forward.
  GoForward(GURL("data:text/html;charset=utf-8,<div id=pagename>Page C</div>"),
            forward_state);
  EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_c, &was_page_c));
  EXPECT_EQ(1, was_page_c);

  // Go back.
  GoBack(GURL("data:text/html;charset=utf-8,<div id=pagename>Page B</div>"),
         back_state2);
  EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_b, &was_page_b));
  EXPECT_EQ(1, was_page_b);

  forward_state = GetCurrentPageState();

  // Go back.
  GoBack(GURL("data:text/html;charset=utf-8,<div id=pagename>Page A</div>"),
         page_a_state);
  EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_a, &was_page_a));
  EXPECT_EQ(1, was_page_a);

  // Go forward.
  GoForward(GURL("data:text/html;charset=utf-8,<div id=pagename>Page B</div>"),
            forward_state);
  EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_b, &was_page_b));
  EXPECT_EQ(1, was_page_b);
}

#if defined(OS_MACOSX) || defined(USE_AURA)
TEST_F(RenderViewImplTest, GetCompositionCharacterBoundsTest) {
#if defined(OS_WIN)
  // http://crbug.com/304193
  if (base::win::GetVersion() < base::win::VERSION_VISTA)
    return;
#endif

  LoadHTML("<textarea id=\"test\" cols=\"100\"></textarea>");
  ExecuteJavaScriptForTests("document.getElementById('test').focus();");

  const base::string16 empty_string;
  const std::vector<blink::WebCompositionUnderline> empty_underline;
  std::vector<gfx::Rect> bounds;
  view()->OnSetFocus(true);

  // ASCII composition
  const base::string16 ascii_composition = base::UTF8ToUTF16("aiueo");
  view()->OnImeSetComposition(ascii_composition, empty_underline,
                              gfx::Range::InvalidRange(), 0, 0);
  view()->GetCompositionCharacterBounds(&bounds);
  ASSERT_EQ(ascii_composition.size(), bounds.size());

  for (size_t i = 0; i < bounds.size(); ++i)
    EXPECT_LT(0, bounds[i].width());
  view()->OnImeCommitText(empty_string,
                          std::vector<blink::WebCompositionUnderline>(),
                          gfx::Range::InvalidRange(), 0);

  // Non surrogate pair unicode character.
  const base::string16 unicode_composition = base::UTF8ToUTF16(
      "\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86\xE3\x81\x88\xE3\x81\x8A");
  view()->OnImeSetComposition(unicode_composition, empty_underline,
                              gfx::Range::InvalidRange(), 0, 0);
  view()->GetCompositionCharacterBounds(&bounds);
  ASSERT_EQ(unicode_composition.size(), bounds.size());
  for (size_t i = 0; i < bounds.size(); ++i)
    EXPECT_LT(0, bounds[i].width());
  view()->OnImeCommitText(empty_string, empty_underline,
                          gfx::Range::InvalidRange(), 0);

  // Surrogate pair character.
  const base::string16 surrogate_pair_char =
      base::UTF8ToUTF16("\xF0\xA0\xAE\x9F");
  view()->OnImeSetComposition(surrogate_pair_char,
                              empty_underline,
                              gfx::Range::InvalidRange(),
                              0,
                              0);
  view()->GetCompositionCharacterBounds(&bounds);
  ASSERT_EQ(surrogate_pair_char.size(), bounds.size());
  EXPECT_LT(0, bounds[0].width());
  EXPECT_EQ(0, bounds[1].width());
  view()->OnImeCommitText(empty_string, empty_underline,
                          gfx::Range::InvalidRange(), 0);

  // Mixed string.
  const base::string16 surrogate_pair_mixed_composition =
      surrogate_pair_char + base::UTF8ToUTF16("\xE3\x81\x82") +
      surrogate_pair_char + base::UTF8ToUTF16("b") + surrogate_pair_char;
  const size_t utf16_length = 8UL;
  const bool is_surrogate_pair_empty_rect[8] = {
    false, true, false, false, true, false, false, true };
  view()->OnImeSetComposition(surrogate_pair_mixed_composition,
                              empty_underline,
                              gfx::Range::InvalidRange(),
                              0,
                              0);
  view()->GetCompositionCharacterBounds(&bounds);
  ASSERT_EQ(utf16_length, bounds.size());
  for (size_t i = 0; i < utf16_length; ++i) {
    if (is_surrogate_pair_empty_rect[i]) {
      EXPECT_EQ(0, bounds[i].width());
    } else {
      EXPECT_LT(0, bounds[i].width());
    }
  }
  view()->OnImeCommitText(empty_string, empty_underline,
                          gfx::Range::InvalidRange(), 0);
}
#endif

TEST_F(RenderViewImplTest, SetEditableSelectionAndComposition) {
  // Load an HTML page consisting of an input field.
  LoadHTML("<html>"
           "<head>"
           "</head>"
           "<body>"
           "<input id=\"test1\" value=\"some test text hello\"></input>"
           "</body>"
           "</html>");
  ExecuteJavaScriptForTests("document.getElementById('test1').focus();");
  frame()->SetEditableSelectionOffsets(4, 8);
  const std::vector<blink::WebCompositionUnderline> empty_underline;
  frame()->SetCompositionFromExistingText(7, 10, empty_underline);
  blink::WebInputMethodController* controller =
      frame()->GetWebFrame()->GetInputMethodController();
  blink::WebTextInputInfo info = controller->TextInputInfo();
  EXPECT_EQ(4, info.selection_start);
  EXPECT_EQ(8, info.selection_end);
  EXPECT_EQ(7, info.composition_start);
  EXPECT_EQ(10, info.composition_end);
  frame()->CollapseSelection();
  info = controller->TextInputInfo();
  EXPECT_EQ(8, info.selection_start);
  EXPECT_EQ(8, info.selection_end);
}

TEST_F(RenderViewImplTest, OnExtendSelectionAndDelete) {
  // Load an HTML page consisting of an input field.
  LoadHTML("<html>"
           "<head>"
           "</head>"
           "<body>"
           "<input id=\"test1\" value=\"abcdefghijklmnopqrstuvwxyz\"></input>"
           "</body>"
           "</html>");
  ExecuteJavaScriptForTests("document.getElementById('test1').focus();");
  frame()->SetEditableSelectionOffsets(10, 10);
  frame()->ExtendSelectionAndDelete(3, 4);
  blink::WebInputMethodController* controller =
      frame()->GetWebFrame()->GetInputMethodController();
  blink::WebTextInputInfo info = controller->TextInputInfo();
  EXPECT_EQ("abcdefgopqrstuvwxyz", info.value);
  EXPECT_EQ(7, info.selection_start);
  EXPECT_EQ(7, info.selection_end);
  frame()->SetEditableSelectionOffsets(4, 8);
  frame()->ExtendSelectionAndDelete(2, 5);
  info = controller->TextInputInfo();
  EXPECT_EQ("abuvwxyz", info.value);
  EXPECT_EQ(2, info.selection_start);
  EXPECT_EQ(2, info.selection_end);
}

TEST_F(RenderViewImplTest, OnDeleteSurroundingText) {
  // Load an HTML page consisting of an input field.
  LoadHTML(
      "<html>"
      "<head>"
      "</head>"
      "<body>"
      "<input id=\"test1\" value=\"abcdefghijklmnopqrstuvwxyz\"></input>"
      "</body>"
      "</html>");
  ExecuteJavaScriptForTests("document.getElementById('test1').focus();");

  frame()->SetEditableSelectionOffsets(10, 10);
  frame()->DeleteSurroundingText(3, 4);
  blink::WebInputMethodController* controller =
      frame()->GetWebFrame()->GetInputMethodController();
  blink::WebTextInputInfo info = controller->TextInputInfo();
  EXPECT_EQ("abcdefgopqrstuvwxyz", info.value);
  EXPECT_EQ(7, info.selection_start);
  EXPECT_EQ(7, info.selection_end);

  frame()->SetEditableSelectionOffsets(4, 8);
  frame()->DeleteSurroundingText(2, 5);
  info = controller->TextInputInfo();
  EXPECT_EQ("abefgouvwxyz", info.value);
  EXPECT_EQ(2, info.selection_start);
  EXPECT_EQ(6, info.selection_end);

  frame()->SetEditableSelectionOffsets(5, 5);
  frame()->DeleteSurroundingText(10, 0);
  info = controller->TextInputInfo();
  EXPECT_EQ("ouvwxyz", info.value);
  EXPECT_EQ(0, info.selection_start);
  EXPECT_EQ(0, info.selection_end);

  frame()->DeleteSurroundingText(0, 10);
  info = controller->TextInputInfo();
  EXPECT_EQ("", info.value);
  EXPECT_EQ(0, info.selection_start);
  EXPECT_EQ(0, info.selection_end);

  frame()->DeleteSurroundingText(10, 10);
  info = controller->TextInputInfo();
  EXPECT_EQ("", info.value);

  EXPECT_EQ(0, info.selection_start);
  EXPECT_EQ(0, info.selection_end);
}

TEST_F(RenderViewImplTest, OnDeleteSurroundingTextInCodePoints) {
  // Load an HTML page consisting of an input field.
  LoadHTML(
      // "ab" + trophy + space + "cdef" + trophy + space + "gh".
      "<input id=\"test1\" value=\"ab&#x1f3c6; cdef&#x1f3c6; gh\">");
  ExecuteJavaScriptForTests("document.getElementById('test1').focus();");

  frame()->SetEditableSelectionOffsets(4, 4);
  frame()->DeleteSurroundingTextInCodePoints(2, 2);
  blink::WebInputMethodController* controller =
      frame()->GetWebFrame()->GetInputMethodController();
  blink::WebTextInputInfo info = controller->TextInputInfo();
  // "a" + "def" + trophy + space + "gh".
  EXPECT_EQ(WebString::FromUTF8("adef\xF0\x9F\x8F\x86 gh"), info.value);
  EXPECT_EQ(1, info.selection_start);
  EXPECT_EQ(1, info.selection_end);

  frame()->SetEditableSelectionOffsets(1, 3);
  frame()->DeleteSurroundingTextInCodePoints(1, 4);
  info = controller->TextInputInfo();
  EXPECT_EQ("deh", info.value);
  EXPECT_EQ(0, info.selection_start);
  EXPECT_EQ(2, info.selection_end);
}

// Test that the navigating specific frames works correctly.
TEST_F(RenderViewImplTest, NavigateSubframe) {
  // Load page A.
  LoadHTML("hello <iframe srcdoc='fail' name='frame'></iframe>");

  // Navigate the frame only.
  CommonNavigationParams common_params;
  RequestNavigationParams request_params;
  common_params.url = GURL("data:text/html,world");
  common_params.navigation_type = FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT;
  common_params.transition = ui::PAGE_TRANSITION_TYPED;
  common_params.navigation_start = base::TimeTicks::FromInternalValue(1);
  request_params.current_history_list_length = 1;
  request_params.current_history_list_offset = 0;
  request_params.pending_history_list_offset = 1;

  TestRenderFrame* subframe =
      static_cast<TestRenderFrame*>(RenderFrameImpl::FromWebFrame(
          view()->webview()->FindFrameByName("frame")));
  subframe->Navigate(common_params, StartNavigationParams(), request_params);
  FrameLoadWaiter(subframe).Wait();

  // Copy the document content to std::wstring and compare with the
  // expected result.
  const int kMaxOutputCharacters = 256;
  std::string output = WebFrameContentDumper::DumpWebViewAsText(
                           view()->GetWebView(), kMaxOutputCharacters)
                           .Utf8();
  EXPECT_EQ(output, "hello  \n\nworld");
}

// This test ensures that a RenderFrame object is created for the top level
// frame in the RenderView.
TEST_F(RenderViewImplTest, BasicRenderFrame) {
  EXPECT_TRUE(view()->main_render_frame_);
}

TEST_F(RenderViewImplTest, MessageOrderInDidChangeSelection) {
  LoadHTML("<textarea id=\"test\"></textarea>");

  view()->SetHandlingInputEventForTesting(true);
  ExecuteJavaScriptForTests("document.getElementById('test').focus();");

  bool is_input_type_called = false;
  bool is_selection_called = false;
  size_t last_input_type = 0;
  size_t last_selection = 0;

  for (size_t i = 0; i < render_thread_->sink().message_count(); ++i) {
    const uint32_t type = render_thread_->sink().GetMessageAt(i)->type();
    if (type == ViewHostMsg_TextInputStateChanged::ID) {
      is_input_type_called = true;
      last_input_type = i;
    } else if (type == FrameHostMsg_SelectionChanged::ID) {
      is_selection_called = true;
      last_selection = i;
    }
  }

  EXPECT_TRUE(is_input_type_called);
  EXPECT_TRUE(is_selection_called);

  // InputTypeChange shold be called earlier than SelectionChanged.
  EXPECT_LT(last_input_type, last_selection);
}

class RendererErrorPageTest : public RenderViewImplTest {
 public:
  ContentRendererClient* CreateContentRendererClient() override {
    return new TestContentRendererClient;
  }

  RenderViewImpl* view() {
    return static_cast<RenderViewImpl*>(view_);
  }

  RenderFrameImpl* frame() {
    return static_cast<RenderFrameImpl*>(view()->GetMainRenderFrame());
  }

 private:
  class TestContentRendererClient : public ContentRendererClient {
   public:
    bool ShouldSuppressErrorPage(RenderFrame* render_frame,
                                 const GURL& url) override {
      return url == "http://example.com/suppress";
    }

    void GetNavigationErrorStrings(content::RenderFrame* render_frame,
                                   const blink::WebURLRequest& failed_request,
                                   const blink::WebURLError& error,
                                   std::string* error_html,
                                   base::string16* error_description) override {
      if (error_html)
        *error_html = "A suffusion of yellow.";
    }

    bool HasErrorPage(int http_status_code,
                      std::string* error_domain) override {
      return true;
    }
  };
};

#if defined(OS_ANDROID)
// Crashing on Android: http://crbug.com/311341
#define MAYBE_Suppresses DISABLED_Suppresses
#else
#define MAYBE_Suppresses Suppresses
#endif

TEST_F(RendererErrorPageTest, MAYBE_Suppresses) {
  WebURLError error;
  error.domain = WebString::FromUTF8(net::kErrorDomain);
  error.reason = net::ERR_FILE_NOT_FOUND;
  error.unreachable_url = GURL("http://example.com/suppress");

  // Start a load that will reach provisional state synchronously,
  // but won't complete synchronously.
  CommonNavigationParams common_params;
  common_params.navigation_type = FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT;
  common_params.url = GURL("data:text/html,test data");
  TestRenderFrame* main_frame = static_cast<TestRenderFrame*>(frame());
  main_frame->Navigate(common_params, StartNavigationParams(),
                       RequestNavigationParams());

  // An error occurred.
  main_frame->DidFailProvisionalLoad(error, blink::kWebStandardCommit);
  const int kMaxOutputCharacters = 22;
  EXPECT_EQ("", WebFrameContentDumper::DumpWebViewAsText(view()->GetWebView(),
                                                         kMaxOutputCharacters)
                    .Ascii());
}

#if defined(OS_ANDROID)
// Crashing on Android: http://crbug.com/311341
#define MAYBE_DoesNotSuppress DISABLED_DoesNotSuppress
#else
#define MAYBE_DoesNotSuppress DoesNotSuppress
#endif

TEST_F(RendererErrorPageTest, MAYBE_DoesNotSuppress) {
  WebURLError error;
  error.domain = WebString::FromUTF8(net::kErrorDomain);
  error.reason = net::ERR_FILE_NOT_FOUND;
  error.unreachable_url = GURL("http://example.com/dont-suppress");

  // Start a load that will reach provisional state synchronously,
  // but won't complete synchronously.
  CommonNavigationParams common_params;
  common_params.navigation_type = FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT;
  common_params.url = GURL("data:text/html,test data");
  TestRenderFrame* main_frame = static_cast<TestRenderFrame*>(frame());
  main_frame->Navigate(common_params, StartNavigationParams(),
                       RequestNavigationParams());

  // An error occurred.
  main_frame->DidFailProvisionalLoad(error, blink::kWebStandardCommit);

  // The error page itself is loaded asynchronously.
  FrameLoadWaiter(main_frame).Wait();
  const int kMaxOutputCharacters = 22;
  EXPECT_EQ("A suffusion of yellow.",
            WebFrameContentDumper::DumpWebViewAsText(view()->GetWebView(),
                                                     kMaxOutputCharacters)
                .Ascii());
}

#if defined(OS_ANDROID)
// Crashing on Android: http://crbug.com/311341
#define MAYBE_HttpStatusCodeErrorWithEmptyBody \
  DISABLED_HttpStatusCodeErrorWithEmptyBody
#else
#define MAYBE_HttpStatusCodeErrorWithEmptyBody HttpStatusCodeErrorWithEmptyBody
#endif
TEST_F(RendererErrorPageTest, MAYBE_HttpStatusCodeErrorWithEmptyBody) {
  blink::WebURLResponse response;
  response.SetHTTPStatusCode(503);

  // Start a load that will reach provisional state synchronously,
  // but won't complete synchronously.
  CommonNavigationParams common_params;
  common_params.navigation_type = FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT;
  common_params.url = GURL("data:text/html,test data");
  TestRenderFrame* main_frame = static_cast<TestRenderFrame*>(frame());
  main_frame->Navigate(common_params, StartNavigationParams(),
                       RequestNavigationParams());

  // Emulate a 4xx/5xx main resource response with an empty body.
  main_frame->DidReceiveResponse(response);
  main_frame->DidFinishDocumentLoad();
  main_frame->RunScriptsAtDocumentReady(true);

  // The error page itself is loaded asynchronously.
  FrameLoadWaiter(main_frame).Wait();
  const int kMaxOutputCharacters = 22;
  EXPECT_EQ("A suffusion of yellow.",
            WebFrameContentDumper::DumpWebViewAsText(view()->GetWebView(),
                                                     kMaxOutputCharacters)
                .Ascii());
}

// Ensure the render view sends favicon url update events correctly.
TEST_F(RenderViewImplTest, SendFaviconURLUpdateEvent) {
  // An event should be sent when a favicon url exists.
  LoadHTML("<html>"
           "<head>"
           "<link rel='icon' href='http://www.google.com/favicon.ico'>"
           "</head>"
           "</html>");
  EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching(
      ViewHostMsg_UpdateFaviconURL::ID));
  render_thread_->sink().ClearMessages();

  // An event should not be sent if no favicon url exists. This is an assumption
  // made by some of Chrome's favicon handling.
  LoadHTML("<html>"
           "<head>"
           "</head>"
           "</html>");
  EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
      ViewHostMsg_UpdateFaviconURL::ID));
}

TEST_F(RenderViewImplTest, FocusElementCallsFocusedNodeChanged) {
  LoadHTML("<input id='test1' value='hello1'></input>"
           "<input id='test2' value='hello2'></input>");

  ExecuteJavaScriptForTests("document.getElementById('test1').focus();");
  const IPC::Message* msg1 = render_thread_->sink().GetFirstMessageMatching(
      FrameHostMsg_FocusedNodeChanged::ID);
  EXPECT_TRUE(msg1);

  FrameHostMsg_FocusedNodeChanged::Param params;
  FrameHostMsg_FocusedNodeChanged::Read(msg1, &params);
  EXPECT_TRUE(std::get<0>(params));
  render_thread_->sink().ClearMessages();

  ExecuteJavaScriptForTests("document.getElementById('test2').focus();");
  const IPC::Message* msg2 = render_thread_->sink().GetFirstMessageMatching(
      FrameHostMsg_FocusedNodeChanged::ID);
  EXPECT_TRUE(msg2);
  FrameHostMsg_FocusedNodeChanged::Read(msg2, &params);
  EXPECT_TRUE(std::get<0>(params));
  render_thread_->sink().ClearMessages();

  view()->webview()->ClearFocusedElement();
  const IPC::Message* msg3 = render_thread_->sink().GetFirstMessageMatching(
      FrameHostMsg_FocusedNodeChanged::ID);
  EXPECT_TRUE(msg3);
  FrameHostMsg_FocusedNodeChanged::Read(msg3, &params);
  EXPECT_FALSE(std::get<0>(params));
  render_thread_->sink().ClearMessages();
}

TEST_F(RenderViewImplTest, ServiceWorkerNetworkProviderSetup) {
  blink::WebServiceWorkerNetworkProvider* webprovider = nullptr;
  ServiceWorkerNetworkProvider* provider = nullptr;
  RequestExtraData* extra_data = nullptr;

  // Make sure each new document has a new provider and
  // that the main request is tagged with the provider's id.
  LoadHTML("<b>A Document</b>");
  ASSERT_TRUE(GetMainFrame()->DataSource());
  webprovider = GetMainFrame()->DataSource()->GetServiceWorkerNetworkProvider();
  ASSERT_TRUE(webprovider);
  extra_data = static_cast<RequestExtraData*>(
      GetMainFrame()->DataSource()->GetRequest().GetExtraData());
  ASSERT_TRUE(extra_data);
  provider = ServiceWorkerNetworkProvider::FromWebServiceWorkerNetworkProvider(
      webprovider);
  ASSERT_TRUE(provider);
  EXPECT_EQ(extra_data->service_worker_provider_id(), provider->provider_id());
  int provider1_id = provider->provider_id();

  LoadHTML("<b>New Document B Goes Here</b>");
  ASSERT_TRUE(GetMainFrame()->DataSource());
  webprovider = GetMainFrame()->DataSource()->GetServiceWorkerNetworkProvider();
  ASSERT_TRUE(provider);
  provider = ServiceWorkerNetworkProvider::FromWebServiceWorkerNetworkProvider(
      webprovider);
  ASSERT_TRUE(provider);
  EXPECT_NE(provider1_id, provider->provider_id());
  extra_data = static_cast<RequestExtraData*>(
      GetMainFrame()->DataSource()->GetRequest().GetExtraData());
  ASSERT_TRUE(extra_data);
  EXPECT_EQ(extra_data->service_worker_provider_id(), provider->provider_id());

  // See that subresource requests are also tagged with the provider's id.
  EXPECT_EQ(frame(), RenderFrameImpl::FromWebFrame(GetMainFrame()));
  blink::WebURLRequest request(GURL("http://foo.com"));
  request.SetRequestContext(blink::WebURLRequest::kRequestContextSubresource);
  blink::WebURLResponse redirect_response;
  webprovider->WillSendRequest(request);
  extra_data = static_cast<RequestExtraData*>(request.GetExtraData());
  ASSERT_TRUE(extra_data);
  EXPECT_EQ(extra_data->service_worker_provider_id(), provider->provider_id());
}

TEST_F(RenderViewImplTest, OnSetAccessibilityMode) {
  ASSERT_TRUE(frame()->accessibility_mode().is_mode_off());
  ASSERT_FALSE(frame()->render_accessibility());

  frame()->SetAccessibilityMode(kAccessibilityModeWebContentsOnly);
  ASSERT_TRUE(frame()->accessibility_mode() ==
              kAccessibilityModeWebContentsOnly);
  ASSERT_TRUE(frame()->render_accessibility());

  frame()->SetAccessibilityMode(AccessibilityMode());
  ASSERT_TRUE(frame()->accessibility_mode().is_mode_off());
  ASSERT_FALSE(frame()->render_accessibility());

  frame()->SetAccessibilityMode(kAccessibilityModeComplete);
  ASSERT_TRUE(frame()->accessibility_mode() == kAccessibilityModeComplete);
  ASSERT_TRUE(frame()->render_accessibility());
}

// Checks that when a navigation starts in the renderer, |navigation_start| is
// recorded at an appropriate time and is passed in the corresponding message.
TEST_F(RenderViewImplTest, RendererNavigationStartTransmittedToBrowser) {
  base::TimeTicks lower_bound_navigation_start(base::TimeTicks::Now());
  frame()->GetWebFrame()->LoadHTMLString(
      "hello world", blink::WebURL(GURL("data:text/html,")));

  FrameHostMsg_DidStartProvisionalLoad::Param host_nav_params =
      ProcessAndReadIPC<FrameHostMsg_DidStartProvisionalLoad>();
  base::TimeTicks transmitted_start = std::get<2>(host_nav_params);
  EXPECT_FALSE(transmitted_start.is_null());
  EXPECT_LE(lower_bound_navigation_start, transmitted_start);
}

// Checks that a browser-initiated navigation in an initial document that was
// not accessed uses browser-side timestamp.
// This test assumes that |frame()| contains an unaccessed initial document at
// start.
TEST_F(RenderViewImplTest, BrowserNavigationStart) {
  auto common_params = MakeCommonNavigationParams(-TimeDelta::FromSeconds(1));

  frame()->Navigate(common_params, StartNavigationParams(),
                    RequestNavigationParams());
  FrameHostMsg_DidStartProvisionalLoad::Param nav_params =
      ProcessAndReadIPC<FrameHostMsg_DidStartProvisionalLoad>();
  EXPECT_EQ(common_params.navigation_start, std::get<2>(nav_params));
}

// Sanity check for the Navigation Timing API |navigationStart| override. We
// are asserting only most basic constraints, as TimeTicks (passed as the
// override) are not comparable with the wall time (returned by the Blink API).
TEST_F(RenderViewImplTest, BrowserNavigationStartSanitized) {
  // Verify that a navigation that claims to have started in the future - 42
  // days from now is *not* reported as one that starts in the future; as we
  // sanitize the override allowing a maximum of ::Now().
  auto late_common_params = MakeCommonNavigationParams(TimeDelta::FromDays(42));
  late_common_params.method = "POST";

  frame()->Navigate(late_common_params, StartNavigationParams(),
                    RequestNavigationParams());
  base::RunLoop().RunUntilIdle();
  base::Time after_navigation =
      base::Time::Now() + base::TimeDelta::FromDays(1);

  base::Time late_nav_reported_start =
      base::Time::FromDoubleT(GetMainFrame()->Performance().NavigationStart());
  EXPECT_LE(late_nav_reported_start, after_navigation);
}

// Checks that a browser-initiated navigation in an initial document that has
// been accessed does not use browser-side timestamp (there may be arbitrary
// content and/or scripts injected, including beforeunload handler that shows
// a confirmation dialog).
// If PlzNavigate is enabled, browser-side timestamp is always used.
TEST_F(RenderViewImplTest, NavigationStartWhenInitialDocumentWasAccessed) {
  // Trigger a didAccessInitialDocument notification.
  ExecuteJavaScriptForTests("document.title = 'Hi!';");

  auto common_params = MakeCommonNavigationParams(-TimeDelta::FromSeconds(1));
  frame()->Navigate(common_params, StartNavigationParams(),
                    RequestNavigationParams());

  FrameHostMsg_DidStartProvisionalLoad::Param nav_params =
      ProcessAndReadIPC<FrameHostMsg_DidStartProvisionalLoad>();
  if (!IsBrowserSideNavigationEnabled())
    EXPECT_GT(std::get<2>(nav_params), common_params.navigation_start);
  else
    EXPECT_EQ(common_params.navigation_start, std::get<2>(nav_params));
}

TEST_F(RenderViewImplTest, NavigationStartForReload) {
  const char url_string[] = "data:text/html,<div>Page</div>";
  // Navigate once, then reload.
  LoadHTML(url_string);
  base::RunLoop().RunUntilIdle();
  render_thread_->sink().ClearMessages();

  CommonNavigationParams common_params;
  common_params.url = GURL(url_string);
  common_params.navigation_type =
      FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL;
  common_params.transition = ui::PAGE_TRANSITION_RELOAD;

  // The browser navigation_start should not be used because beforeunload will
  // be fired during Navigate.
  frame()->Navigate(common_params, StartNavigationParams(),
                    RequestNavigationParams());

  FrameHostMsg_DidStartProvisionalLoad::Param host_nav_params =
      ProcessAndReadIPC<FrameHostMsg_DidStartProvisionalLoad>();

  if (!IsBrowserSideNavigationEnabled()) {
    // The browser navigation_start should not be used because beforeunload was
    // fired during Navigate.
    EXPECT_PRED2(TimeTicksGT, std::get<2>(host_nav_params),
                 common_params.navigation_start);
  } else {
    // PlzNavigate: the browser navigation_start is always used.
    EXPECT_EQ(common_params.navigation_start, std::get<2>(host_nav_params));
  }
}

TEST_F(RenderViewImplTest, NavigationStartForSameProcessHistoryNavigation) {
  LoadHTML("<div id=pagename>Page A</div>");
  LoadHTML("<div id=pagename>Page B</div>");
  PageState back_state = GetCurrentPageState();
  LoadHTML("<div id=pagename>Page C</div>");
  PageState forward_state = GetCurrentPageState();
  base::RunLoop().RunUntilIdle();
  render_thread_->sink().ClearMessages();

  // Go back.
  CommonNavigationParams common_params_back;
  common_params_back.url =
      GURL("data:text/html;charset=utf-8,<div id=pagename>Page B</div>");
  common_params_back.transition = ui::PAGE_TRANSITION_FORWARD_BACK;
  common_params_back.navigation_type =
      FrameMsg_Navigate_Type::HISTORY_DIFFERENT_DOCUMENT;
  GoToOffsetWithParams(-1, back_state, common_params_back,
                       StartNavigationParams(), RequestNavigationParams());
  FrameHostMsg_DidStartProvisionalLoad::Param host_nav_params =
      ProcessAndReadIPC<FrameHostMsg_DidStartProvisionalLoad>();
  if (!IsBrowserSideNavigationEnabled()) {
    // The browser navigation_start should not be used because beforeunload was
    // fired during GoToOffsetWithParams.
    EXPECT_PRED2(TimeTicksGT, std::get<2>(host_nav_params),
                 common_params_back.navigation_start);
  } else {
    // PlzNavigate: the browser navigation_start is always used.
    EXPECT_EQ(common_params_back.navigation_start,
              std::get<2>(host_nav_params));
  }
  render_thread_->sink().ClearMessages();

  // Go forward.
  CommonNavigationParams common_params_forward;
  common_params_forward.url =
      GURL("data:text/html;charset=utf-8,<div id=pagename>Page C</div>");
  common_params_forward.transition = ui::PAGE_TRANSITION_FORWARD_BACK;
  common_params_forward.navigation_type =
      FrameMsg_Navigate_Type::HISTORY_DIFFERENT_DOCUMENT;
  GoToOffsetWithParams(1, forward_state, common_params_forward,
                       StartNavigationParams(), RequestNavigationParams());
  FrameHostMsg_DidStartProvisionalLoad::Param host_nav_params2 =
      ProcessAndReadIPC<FrameHostMsg_DidStartProvisionalLoad>();
  if (!IsBrowserSideNavigationEnabled()) {
    EXPECT_PRED2(TimeTicksGT, std::get<2>(host_nav_params2),
                 common_params_forward.navigation_start);
  } else {
    EXPECT_EQ(common_params_forward.navigation_start,
              std::get<2>(host_nav_params2));
  }
}

TEST_F(RenderViewImplTest, NavigationStartForCrossProcessHistoryNavigation) {
  auto common_params = MakeCommonNavigationParams(-TimeDelta::FromSeconds(1));
  common_params.transition = ui::PAGE_TRANSITION_FORWARD_BACK;
  common_params.navigation_type =
      FrameMsg_Navigate_Type::HISTORY_DIFFERENT_DOCUMENT;

  RequestNavigationParams request_params;
  request_params.page_state =
      PageState::CreateForTesting(common_params.url, false, nullptr, nullptr);
  request_params.nav_entry_id = 42;
  request_params.pending_history_list_offset = 1;
  request_params.current_history_list_offset = 0;
  request_params.current_history_list_length = 1;
  frame()->Navigate(common_params, StartNavigationParams(), request_params);

  FrameHostMsg_DidStartProvisionalLoad::Param host_nav_params =
      ProcessAndReadIPC<FrameHostMsg_DidStartProvisionalLoad>();
  EXPECT_EQ(std::get<2>(host_nav_params), common_params.navigation_start);
}

TEST_F(RenderViewImplTest, PreferredSizeZoomed) {
  LoadHTML("<body style='margin:0;'><div style='display:inline-block; "
           "width:400px; height:400px;'/></body>");
  view()->webview()->MainFrame()->SetCanHaveScrollbars(false);
  EnablePreferredSizeMode();

  gfx::Size size = GetPreferredSize();
  EXPECT_EQ(gfx::Size(400, 400), size);

  SetZoomLevel(ZoomFactorToZoomLevel(2.0));
  size = GetPreferredSize();
  EXPECT_EQ(gfx::Size(800, 800), size);
}

// Ensure the RenderViewImpl history list is properly updated when starting a
// new browser-initiated navigation.
TEST_F(RenderViewImplTest, HistoryIsProperlyUpdatedOnNavigation) {
  EXPECT_EQ(0, view()->HistoryBackListCount());
  EXPECT_EQ(0, view()->HistoryBackListCount() +
                   view()->HistoryForwardListCount() + 1);

  // Receive a Navigate message with history parameters.
  RequestNavigationParams request_params;
  request_params.current_history_list_length = 2;
  request_params.current_history_list_offset = 1;
  request_params.pending_history_list_offset = 2;
  frame()->Navigate(CommonNavigationParams(), StartNavigationParams(),
                    request_params);

  // The history list in RenderView should have been updated.
  EXPECT_EQ(1, view()->HistoryBackListCount());
  EXPECT_EQ(2, view()->HistoryBackListCount() +
                   view()->HistoryForwardListCount() + 1);
}

// IPC Listener that runs a callback when a console.log() is executed from
// javascript.
class ConsoleCallbackFilter : public IPC::Listener {
 public:
  explicit ConsoleCallbackFilter(
      base::Callback<void(const base::string16&)> callback)
      : callback_(callback) {}

  bool OnMessageReceived(const IPC::Message& msg) override {
    bool handled = true;
    IPC_BEGIN_MESSAGE_MAP(ConsoleCallbackFilter, msg)
      IPC_MESSAGE_HANDLER(FrameHostMsg_DidAddMessageToConsole,
                          OnDidAddMessageToConsole)
      IPC_MESSAGE_UNHANDLED(handled = false)
    IPC_END_MESSAGE_MAP()
    return handled;
  }

  void OnDidAddMessageToConsole(int32_t,
                                const base::string16& message,
                                int32_t,
                                const base::string16&) {
    callback_.Run(message);
  }

 private:
  base::Callback<void(const base::string16&)> callback_;
};

// Tests that there's no UaF after dispatchBeforeUnloadEvent.
// See https://crbug.com/666714.
TEST_F(RenderViewImplTest, DispatchBeforeUnloadCanDetachFrame) {
  LoadHTML(
      "<script>window.onbeforeunload = function() { "
      "window.console.log('OnBeforeUnload called'); }</script>");

  // Creates a callback that swaps the frame when the 'OnBeforeUnload called'
  // log is printed from the beforeunload handler.
  std::unique_ptr<ConsoleCallbackFilter> callback_filter(
      new ConsoleCallbackFilter(base::Bind(
          [](RenderFrameImpl* frame, const base::string16& msg) {
            // Makes sure this happens during the beforeunload handler.
            EXPECT_EQ(base::UTF8ToUTF16("OnBeforeUnload called"), msg);

            // Swaps the main frame.
            frame->OnMessageReceived(FrameMsg_SwapOut(
                frame->GetRoutingID(), 1, false, FrameReplicationState()));
          },
          base::Unretained(frame()))));
  render_thread_->sink().AddFilter(callback_filter.get());

  // Simulates a BeforeUnload IPC received from the browser.
  frame()->OnMessageReceived(
      FrameMsg_BeforeUnload(frame()->GetRoutingID(), false));

  render_thread_->sink().RemoveFilter(callback_filter.get());
}

TEST_F(RenderViewImplBlinkSettingsTest, Default) {
  DoSetUp();
  EXPECT_FALSE(settings()->ViewportEnabled());
}

TEST_F(RenderViewImplBlinkSettingsTest, CommandLine) {
  base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
      switches::kBlinkSettings,
      "multiTargetTapNotificationEnabled=true,viewportEnabled=true");
  DoSetUp();
  EXPECT_TRUE(settings()->MultiTargetTapNotificationEnabled());
  EXPECT_TRUE(settings()->ViewportEnabled());
}

TEST_F(RenderViewImplBlinkSettingsTest, Negative) {
  base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
      switches::kBlinkSettings,
      "multiTargetTapNotificationEnabled=false,viewportEnabled=true");
  DoSetUp();
  EXPECT_FALSE(settings()->MultiTargetTapNotificationEnabled());
  EXPECT_TRUE(settings()->ViewportEnabled());
}

TEST_F(RenderViewImplScaleFactorTest, ConverViewportToWindowWithoutZoomForDSF) {
  DoSetUp();
  if (IsUseZoomForDSFEnabled())
    return;
  SetDeviceScaleFactor(2.f);
  blink::WebRect rect(20, 10, 200, 100);
  view()->ConvertViewportToWindow(&rect);
  EXPECT_EQ(20, rect.x);
  EXPECT_EQ(10, rect.y);
  EXPECT_EQ(200, rect.width);
  EXPECT_EQ(100, rect.height);
}

TEST_F(RenderViewImplScaleFactorTest, ScreenMetricsEmulationWithOriginalDSF1) {
  DoSetUp();
  SetDeviceScaleFactor(1.f);

  LoadHTML("<body style='min-height:1000px;'></body>");
  {
    SCOPED_TRACE("327x415 1dpr");
    TestEmulatedSizeDprDsf(327, 415, 1.f, 1.f);
  }
  {
    SCOPED_TRACE("327x415 1.5dpr");
    TestEmulatedSizeDprDsf(327, 415, 1.5f, 1.f);
  }
  {
    SCOPED_TRACE("1005x1102 2dpr");
    TestEmulatedSizeDprDsf(1005, 1102, 2.f, 1.f);
  }
  {
    SCOPED_TRACE("1005x1102 3dpr");
    TestEmulatedSizeDprDsf(1005, 1102, 3.f, 1.f);
  }

  view()->OnDisableDeviceEmulation();

  blink::WebDeviceEmulationParams params;
  view()->OnEnableDeviceEmulation(params);
  // Don't disable here to test that emulation is being shutdown properly.
}

TEST_F(RenderViewImplScaleFactorTest, ScreenMetricsEmulationWithOriginalDSF2) {
  DoSetUp();
  SetDeviceScaleFactor(2.f);
  float compositor_dsf =
      IsUseZoomForDSFEnabled() ? 1.f : 2.f;

  LoadHTML("<body style='min-height:1000px;'></body>");
  {
    SCOPED_TRACE("327x415 1dpr");
    TestEmulatedSizeDprDsf(327, 415, 1.f, compositor_dsf);
  }
  {
    SCOPED_TRACE("327x415 1.5dpr");
    TestEmulatedSizeDprDsf(327, 415, 1.5f, compositor_dsf);
  }
  {
    SCOPED_TRACE("1005x1102 2dpr");
    TestEmulatedSizeDprDsf(1005, 1102, 2.f, compositor_dsf);
  }
  {
    SCOPED_TRACE("1005x1102 3dpr");
    TestEmulatedSizeDprDsf(1005, 1102, 3.f, compositor_dsf);
  }

  view()->OnDisableDeviceEmulation();

  blink::WebDeviceEmulationParams params;
  view()->OnEnableDeviceEmulation(params);
  // Don't disable here to test that emulation is being shutdown properly.
}

TEST_F(RenderViewImplScaleFactorTest, ConverViewportToWindowWithZoomForDSF) {
  base::CommandLine::ForCurrentProcess()->AppendSwitch(
      switches::kEnableUseZoomForDSF);
  DoSetUp();
  SetDeviceScaleFactor(1.f);
  {
    blink::WebRect rect(20, 10, 200, 100);
    view()->ConvertViewportToWindow(&rect);
    EXPECT_EQ(20, rect.x);
    EXPECT_EQ(10, rect.y);
    EXPECT_EQ(200, rect.width);
    EXPECT_EQ(100, rect.height);
  }

  SetDeviceScaleFactor(2.f);
  {
    blink::WebRect rect(20, 10, 200, 100);
    view()->ConvertViewportToWindow(&rect);
    EXPECT_EQ(10, rect.x);
    EXPECT_EQ(5, rect.y);
    EXPECT_EQ(100, rect.width);
    EXPECT_EQ(50, rect.height);
  }
}

#if defined(OS_MACOSX) || defined(USE_AURA)
TEST_F(RenderViewImplScaleFactorTest,
       DISABLED_GetCompositionCharacterBoundsTest) {  // http://crbug.com/582016
  base::CommandLine::ForCurrentProcess()->AppendSwitch(
      switches::kEnableUseZoomForDSF);
  DoSetUp();
  SetDeviceScaleFactor(1.f);
#if defined(OS_WIN)
  // http://crbug.com/508747
  if (base::win::GetVersion() >= base::win::VERSION_WIN10)
    return;
#endif

  LoadHTML("<textarea id=\"test\"></textarea>");
  ExecuteJavaScriptForTests("document.getElementById('test').focus();");

  const base::string16 empty_string;
  const std::vector<blink::WebCompositionUnderline> empty_underline;
  std::vector<gfx::Rect> bounds_at_1x;
  view()->OnSetFocus(true);

  // ASCII composition
  const base::string16 ascii_composition = base::UTF8ToUTF16("aiueo");
  view()->OnImeSetComposition(ascii_composition, empty_underline,
                              gfx::Range::InvalidRange(), 0, 0);
  view()->GetCompositionCharacterBounds(&bounds_at_1x);
  ASSERT_EQ(ascii_composition.size(), bounds_at_1x.size());

  SetDeviceScaleFactor(2.f);
  std::vector<gfx::Rect> bounds_at_2x;
  view()->GetCompositionCharacterBounds(&bounds_at_2x);
  ASSERT_EQ(bounds_at_1x.size(), bounds_at_2x.size());
  for (size_t i = 0; i < bounds_at_1x.size(); i++) {
    const gfx::Rect& b1 = bounds_at_1x[i];
    const gfx::Rect& b2 = bounds_at_2x[i];
    gfx::Vector2d origin_diff = b1.origin() - b2.origin();

    // The bounds may not be exactly same because the font metrics are different
    // at 1x and 2x. Just make sure that the difference is small.
    EXPECT_LT(origin_diff.x(), 2);
    EXPECT_LT(origin_diff.y(), 2);
    EXPECT_LT(std::abs(b1.width() - b2.width()), 3);
    EXPECT_LT(std::abs(b1.height() - b2.height()), 2);
  }
}
#endif

#if !defined(OS_ANDROID)
// No extensions/autoresize on Android.
namespace {

// Don't use text as it text will change the size in DIP at different
// scale factor.
const char kAutoResizeTestPage[] =
    "<div style='width=20px; height=20px'></div>";

}  // namespace

TEST_F(RenderViewImplScaleFactorTest, AutoResizeWithZoomForDSF) {
  base::CommandLine::ForCurrentProcess()->AppendSwitch(
      switches::kEnableUseZoomForDSF);
  DoSetUp();
  view()->EnableAutoResizeForTesting(gfx::Size(5, 5), gfx::Size(1000, 1000));
  LoadHTML(kAutoResizeTestPage);
  gfx::Size size_at_1x = view()->GetWidget()->size();
  ASSERT_FALSE(size_at_1x.IsEmpty());

  SetDeviceScaleFactor(2.f);
  LoadHTML(kAutoResizeTestPage);
  gfx::Size size_at_2x = view()->GetWidget()->size();
  EXPECT_EQ(size_at_1x, size_at_2x);
}

TEST_F(RenderViewImplScaleFactorTest, AutoResizeWithoutZoomForDSF) {
  DoSetUp();
  view()->EnableAutoResizeForTesting(gfx::Size(5, 5), gfx::Size(1000, 1000));
  LoadHTML(kAutoResizeTestPage);
  gfx::Size size_at_1x = view()->GetWidget()->size();
  ASSERT_FALSE(size_at_1x.IsEmpty());

  SetDeviceScaleFactor(2.f);
  LoadHTML(kAutoResizeTestPage);
  gfx::Size size_at_2x = view()->GetWidget()->size();
  EXPECT_EQ(size_at_1x, size_at_2x);
}

#endif

TEST_F(DevToolsAgentTest, DevToolsResumeOnClose) {
  Attach();
  EXPECT_FALSE(IsPaused());
  DispatchDevToolsMessage("Debugger.enable",
                          "{\"id\":1,\"method\":\"Debugger.enable\"}");

  // Executing javascript will pause the thread and create nested run loop.
  // Posting task simulates message coming from browser.
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE,
      base::Bind(&DevToolsAgentTest::CloseWhilePaused, base::Unretained(this)));
  ExecuteJavaScriptForTests("debugger;");

  // CloseWhilePaused should resume execution and continue here.
  EXPECT_FALSE(IsPaused());
  Detach();
}

TEST_F(DevToolsAgentTest, RuntimeEnableForcesContexts) {
  LoadHTML("<body>page<iframe></iframe></body>");
  Attach();
  DispatchDevToolsMessage("Runtime.enable",
                          "{\"id\":1,\"method\":\"Runtime.enable\"}");
  EXPECT_EQ(2, CountNotifications("Runtime.executionContextCreated"));
}

TEST_F(DevToolsAgentTest, RuntimeEnableForcesContextsAfterNavigation) {
  Attach();
  DispatchDevToolsMessage("Runtime.enable",
                          "{\"id\":1,\"method\":\"Runtime.enable\"}");
  EXPECT_EQ(0, CountNotifications("Runtime.executionContextCreated"));
  LoadHTML("<body>page<iframe></iframe></body>");
  EXPECT_EQ(2, CountNotifications("Runtime.executionContextCreated"));
}

TEST_F(DevToolsAgentTest, RuntimeEvaluateRunMicrotasks) {
  LoadHTML("<body>page</body>");
  Attach();
  DispatchDevToolsMessage("Runtime.enable",
                          "{\"id\":1,\"method\":\"Runtime.enable\"}");
  DispatchDevToolsMessage("Runtime.evaluate",
                          "{\"id\":2,"
                          "\"method\":\"Runtime.evaluate\","
                          "\"params\":{"
                          "\"expression\":\"Promise.resolve().then("
                          "() => console.log(42));\""
                          "}"
                          "}");
  EXPECT_EQ(1, CountNotifications("Runtime.consoleAPICalled"));
}

TEST_F(DevToolsAgentTest, RuntimeCallFunctionOnRunMicrotasks) {
  LoadHTML("<body>page</body>");
  Attach();
  DispatchDevToolsMessage("Runtime.enable",
                          "{\"id\":1,\"method\":\"Runtime.enable\"}");
  DispatchDevToolsMessage("Runtime.evaluate",
                          "{\"id\":2,"
                          "\"method\":\"Runtime.evaluate\","
                          "\"params\":{"
                          "\"expression\":\"window\""
                          "}"
                          "}");

  base::DictionaryValue* root = LastReceivedMessage();
  const base::Value* object_id;
  ASSERT_TRUE(root->Get("result.result.objectId", &object_id));
  std::string object_id_str;
  EXPECT_TRUE(base::JSONWriter::Write(*object_id, &object_id_str));

  DispatchDevToolsMessage("Runtime.callFunctionOn",
                          "{\"id\":3,"
                          "\"method\":\"Runtime.callFunctionOn\","
                          "\"params\":{"
                          "\"objectId\":" +
                              object_id_str +
                              ","
                              "\"functionDeclaration\":\"function foo(){ "
                              "Promise.resolve().then(() => "
                              "console.log(239))}\""
                              "}"
                              "}");
  EXPECT_EQ(1, CountNotifications("Runtime.consoleAPICalled"));
}

TEST_F(DevToolsAgentTest, CallFramesInIsolatedWorld) {
  LoadHTML("<body>page</body>");
  blink::WebScriptSource source1(
      WebString::FromUTF8("function func1() { debugger; }"));
  frame()->GetWebFrame()->ExecuteScriptInIsolatedWorld(17, &source1, 1);

  Attach();
  DispatchDevToolsMessage("Debugger.enable",
                          "{\"id\":1,\"method\":\"Debugger.enable\"}");

  ExpectPauseAndResume(3);
  blink::WebScriptSource source2(
      WebString::FromUTF8("function func2() { func1(); }; func2();"));
  frame()->GetWebFrame()->ExecuteScriptInIsolatedWorld(17, &source2, 1);

  EXPECT_FALSE(IsPaused());
  Detach();
}

}  // namespace content
