Upstream version 11.39.250.0
[platform/framework/web/crosswalk.git] / src / content / renderer / render_view_browsertest.cc
index b06151b..e0441fa 100644 (file)
@@ -8,6 +8,7 @@
 #include "base/memory/shared_memory.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/time/time.h"
 #include "base/win/windows_version.h"
 #include "content/child/request_extra_data.h"
 #include "content/child/service_worker/service_worker_network_provider.h"
@@ -25,6 +26,7 @@
 #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/renderer_accessibility.h"
 #include "content/renderer/accessibility/renderer_accessibility_focus_only.h"
 #include "content/renderer/history_controller.h"
 #include "content/renderer/history_serialization.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/frame_load_waiter.h"
 #include "content/test/mock_keyboard.h"
 #include "net/base/net_errors.h"
 #include "net/cert/cert_status_flags.h"
 #include "third_party/WebKit/public/platform/WebString.h"
 #include "third_party/WebKit/public/platform/WebURLResponse.h"
 #include "third_party/WebKit/public/web/WebDataSource.h"
+#include "third_party/WebKit/public/web/WebDeviceEmulationParams.h"
 #include "third_party/WebKit/public/web/WebHistoryItem.h"
 #include "third_party/WebKit/public/web/WebLocalFrame.h"
+#include "third_party/WebKit/public/web/WebPerformance.h"
 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
 #include "third_party/WebKit/public/web/WebView.h"
 #include "third_party/WebKit/public/web/WebWindowFeatures.h"
@@ -62,6 +66,7 @@
 #include <X11/Xlib.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
 
@@ -82,6 +87,8 @@ 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) {
@@ -126,6 +133,8 @@ class WebUITestWebUIControllerFactory : public WebUIControllerFactory {
   }
 };
 
+}  // namespace
+
 class RenderViewImplTest : public RenderViewTest {
  public:
   RenderViewImplTest() {
@@ -147,6 +156,10 @@ class RenderViewImplTest : public RenderViewTest {
     return static_cast<RenderViewImpl*>(view_);
   }
 
+  int view_page_id() {
+    return view()->page_id_;
+  }
+
   RenderFrameImpl* frame() {
     return static_cast<RenderFrameImpl*>(view()->GetMainRenderFrame());
   }
@@ -177,7 +190,7 @@ class RenderViewImplTest : public RenderViewTest {
     // WM_CHAR sends a composed Unicode character.
     MSG msg1 = { NULL, WM_KEYDOWN, key_code, 0 };
 #if defined(USE_AURA)
-    ui::KeyEvent evt1(msg1, false);
+    ui::KeyEvent evt1(msg1);
     NativeWebKeyboardEvent keydown_event(&evt1);
 #else
     NativeWebKeyboardEvent keydown_event(msg1);
@@ -186,7 +199,7 @@ class RenderViewImplTest : public RenderViewTest {
 
     MSG msg2 = { NULL, WM_CHAR, (*output)[0], 0 };
 #if defined(USE_AURA)
-    ui::KeyEvent evt2(msg2, true);
+    ui::KeyEvent evt2(msg2);
     NativeWebKeyboardEvent char_event(&evt2);
 #else
     NativeWebKeyboardEvent char_event(msg2);
@@ -195,7 +208,7 @@ class RenderViewImplTest : public RenderViewTest {
 
     MSG msg3 = { NULL, WM_KEYUP, key_code, 0 };
 #if defined(USE_AURA)
-    ui::KeyEvent evt3(msg3, false);
+    ui::KeyEvent evt3(msg3);
     NativeWebKeyboardEvent keyup_event(&evt3);
 #else
     NativeWebKeyboardEvent keyup_event(msg3);
@@ -213,21 +226,27 @@ class RenderViewImplTest : public RenderViewTest {
     xevent.InitKeyEvent(ui::ET_KEY_PRESSED,
                         static_cast<ui::KeyboardCode>(key_code),
                         flags);
-    ui::KeyEvent event1(xevent, false);
+    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, true);
+    ui::KeyEvent event2(xevent);
+    event2.set_character(GetCharacterFromKeyCode(event2.key_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, false);
+    ui::KeyEvent event3(xevent);
     NativeWebKeyboardEvent keyup_event(&event3);
     SendNativeKeyEvent(keyup_event);
 
@@ -238,29 +257,21 @@ class RenderViewImplTest : public RenderViewTest {
 #elif defined(USE_OZONE)
     const int flags = ConvertMockKeyboardModifier(modifiers);
 
-    // Ozone's native events are ui::Events. So first create the "native" event,
-    // then create the actual ui::KeyEvent with the native event.
-    ui::KeyEvent keydown_native_event(ui::ET_KEY_PRESSED,
-                                   static_cast<ui::KeyboardCode>(key_code),
-                                   flags,
-                                   true);
-    ui::KeyEvent keydown_event(&keydown_native_event, false);
+    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_native_event(ui::ET_KEY_PRESSED,
-                                   static_cast<ui::KeyboardCode>(key_code),
-                                   flags,
-                                   true);
-    ui::KeyEvent char_event(&char_native_event, true);
+    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_native_event(ui::ET_KEY_RELEASED,
-                                    static_cast<ui::KeyboardCode>(key_code),
-                                    flags,
-                                    true);
-    ui::KeyEvent keyup_event(&keyup_native_event, false);
+    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);
 
@@ -278,7 +289,53 @@ class RenderViewImplTest : public RenderViewTest {
   scoped_ptr<MockKeyboard> mock_keyboard_;
 };
 
-}  // namespace
+TEST_F(RenderViewImplTest, SaveImageFromDataURL) {
+  const IPC::Message* msg1 = render_thread_->sink().GetFirstMessageMatching(
+      ViewHostMsg_SaveImageFromDataURL::ID);
+  EXPECT_FALSE(msg1);
+  render_thread_->sink().ClearMessages();
+
+  const std::string image_data_url =
+      "data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=";
+
+  view()->saveImageFromDataURL(WebString::fromUTF8(image_data_url));
+  ProcessPendingMessages();
+  const IPC::Message* msg2 = render_thread_->sink().GetFirstMessageMatching(
+      ViewHostMsg_SaveImageFromDataURL::ID);
+  EXPECT_TRUE(msg2);
+
+  ViewHostMsg_SaveImageFromDataURL::Param param1;
+  ViewHostMsg_SaveImageFromDataURL::Read(msg2, &param1);
+  EXPECT_EQ(param1.b.length(), image_data_url.length());
+  EXPECT_EQ(param1.b, image_data_url);
+
+  ProcessPendingMessages();
+  render_thread_->sink().ClearMessages();
+
+  const std::string large_data_url(1024 * 1024 * 10 - 1, 'd');
+
+  view()->saveImageFromDataURL(WebString::fromUTF8(large_data_url));
+  ProcessPendingMessages();
+  const IPC::Message* msg3 = render_thread_->sink().GetFirstMessageMatching(
+      ViewHostMsg_SaveImageFromDataURL::ID);
+  EXPECT_TRUE(msg3);
+
+  ViewHostMsg_SaveImageFromDataURL::Param param2;
+  ViewHostMsg_SaveImageFromDataURL::Read(msg3, &param2);
+  EXPECT_EQ(param2.b.length(), large_data_url.length());
+  EXPECT_EQ(param2.b, large_data_url);
+
+  ProcessPendingMessages();
+  render_thread_->sink().ClearMessages();
+
+  const std::string exceeded_data_url(1024 * 1024 * 10 + 1, 'd');
+
+  view()->saveImageFromDataURL(WebString::fromUTF8(exceeded_data_url));
+  ProcessPendingMessages();
+  const IPC::Message* msg4 = render_thread_->sink().GetFirstMessageMatching(
+      ViewHostMsg_SaveImageFromDataURL::ID);
+  EXPECT_FALSE(msg4);
+}
 
 // Test that we get form state change notifications when input fields change.
 TEST_F(RenderViewImplTest, DISABLED_OnNavStateChanged) {
@@ -308,9 +365,10 @@ TEST_F(RenderViewImplTest, OnNavigationHttpPost) {
   // An http url will trigger a resource load so cannot be used here.
   nav_params.url = GURL("data:text/html,<div>Page</div>");
   nav_params.navigation_type = FrameMsg_Navigate_Type::NORMAL;
-  nav_params.transition = PAGE_TRANSITION_TYPED;
+  nav_params.transition = ui::PAGE_TRANSITION_TYPED;
   nav_params.page_id = -1;
   nav_params.is_post = true;
+  nav_params.browser_navigation_start = base::TimeTicks::FromInternalValue(1);
 
   // Set up post data.
   const unsigned char* raw_data = reinterpret_cast<const unsigned char*>(
@@ -354,36 +412,34 @@ TEST_F(RenderViewImplTest, DecideNavigationPolicy) {
 
   // Navigations to normal HTTP URLs can be handled locally.
   blink::WebURLRequest request(GURL("http://foo.com"));
+  blink::WebFrameClient::NavigationPolicyInfo policy_info(request);
+  policy_info.frame = GetMainFrame();
+  policy_info.extraData = &state;
+  policy_info.navigationType = blink::WebNavigationTypeLinkClicked;
+  policy_info.defaultPolicy = blink::WebNavigationPolicyCurrentTab;
   blink::WebNavigationPolicy policy = frame()->decidePolicyForNavigation(
-          GetMainFrame(),
-          &state,
-          request,
-          blink::WebNavigationTypeLinkClicked,
-          blink::WebNavigationPolicyCurrentTab,
-          false);
+          policy_info);
   EXPECT_EQ(blink::WebNavigationPolicyCurrentTab, 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.frame = GetMainFrame();
+  form_policy_info.extraData = &state;
+  form_policy_info.navigationType = blink::WebNavigationTypeFormSubmitted;
+  form_policy_info.defaultPolicy = blink::WebNavigationPolicyCurrentTab;
   form_request.setHTTPMethod("POST");
-  policy = frame()->decidePolicyForNavigation(
-      GetMainFrame(),
-      &state,
-      form_request,
-      blink::WebNavigationTypeFormSubmitted,
-      blink::WebNavigationPolicyCurrentTab,
-      false);
+  policy = frame()->decidePolicyForNavigation(form_policy_info);
   EXPECT_EQ(blink::WebNavigationPolicyIgnore, policy);
 
   // Verify that popup links to WebUI URLs also are sent to browser.
   blink::WebURLRequest popup_request(GURL("chrome://foo"));
-  policy = frame()->decidePolicyForNavigation(
-      GetMainFrame(),
-      &state,
-      popup_request,
-      blink::WebNavigationTypeLinkClicked,
-      blink::WebNavigationPolicyNewForegroundTab,
-      false);
+  blink::WebFrameClient::NavigationPolicyInfo popup_policy_info(popup_request);
+  popup_policy_info.frame = GetMainFrame();
+  popup_policy_info.extraData = &state;
+  popup_policy_info.navigationType = blink::WebNavigationTypeLinkClicked;
+  popup_policy_info.defaultPolicy = blink::WebNavigationPolicyNewForegroundTab;
+  policy = frame()->decidePolicyForNavigation(popup_policy_info);
   EXPECT_EQ(blink::WebNavigationPolicyIgnore, policy);
 }
 
@@ -405,14 +461,16 @@ TEST_F(RenderViewImplTest, DecideNavigationPolicyHandlesAllTopLevel) {
   };
 
   blink::WebURLRequest request(GURL("http://foo.com"));
+  blink::WebFrameClient::NavigationPolicyInfo policy_info(request);
+  policy_info.frame = GetMainFrame();
+  policy_info.extraData = &state;
+  policy_info.defaultPolicy = blink::WebNavigationPolicyCurrentTab;
+
   for (size_t i = 0; i < arraysize(kNavTypes); ++i) {
+    policy_info.navigationType = kNavTypes[i];
+
     blink::WebNavigationPolicy policy = frame()->decidePolicyForNavigation(
-        GetMainFrame(),
-        &state,
-        request,
-        kNavTypes[i],
-        blink::WebNavigationPolicyCurrentTab,
-        false);
+        policy_info);
     EXPECT_EQ(blink::WebNavigationPolicyIgnore, policy);
   }
 }
@@ -426,36 +484,35 @@ TEST_F(RenderViewImplTest, DecideNavigationPolicyForWebUI) {
 
   // 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.frame = GetMainFrame();
+  policy_info.extraData = &state;
+  policy_info.navigationType = blink::WebNavigationTypeLinkClicked;
+  policy_info.defaultPolicy = blink::WebNavigationPolicyCurrentTab;
+
   blink::WebNavigationPolicy policy = frame()->decidePolicyForNavigation(
-      GetMainFrame(),
-      &state,
-      request,
-      blink::WebNavigationTypeLinkClicked,
-      blink::WebNavigationPolicyCurrentTab,
-      false);
+      policy_info);
   EXPECT_EQ(blink::WebNavigationPolicyIgnore, policy);
 
   // Navigations to WebUI URLs will also be sent to browser process.
   blink::WebURLRequest webui_request(GURL("chrome://foo"));
-  policy = frame()->decidePolicyForNavigation(
-      GetMainFrame(),
-      &state,
-      webui_request,
-      blink::WebNavigationTypeLinkClicked,
-      blink::WebNavigationPolicyCurrentTab,
-      false);
+  blink::WebFrameClient::NavigationPolicyInfo webui_policy_info(webui_request);
+  webui_policy_info.frame = GetMainFrame();
+  webui_policy_info.extraData = &state;
+  webui_policy_info.navigationType = blink::WebNavigationTypeLinkClicked;
+  webui_policy_info.defaultPolicy = blink::WebNavigationPolicyCurrentTab;
+  policy = frame()->decidePolicyForNavigation(webui_policy_info);
   EXPECT_EQ(blink::WebNavigationPolicyIgnore, 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.frame = GetMainFrame();
+  data_policy_info.extraData = &state;
+  data_policy_info.navigationType = blink::WebNavigationTypeFormSubmitted;
+  data_policy_info.defaultPolicy = blink::WebNavigationPolicyCurrentTab;
   data_request.setHTTPMethod("POST");
-  policy = frame()->decidePolicyForNavigation(
-      GetMainFrame(),
-      &state,
-      data_request,
-      blink::WebNavigationTypeFormSubmitted,
-      blink::WebNavigationPolicyCurrentTab,
-      false);
+  policy = frame()->decidePolicyForNavigation(data_policy_info);
   EXPECT_EQ(blink::WebNavigationPolicyIgnore, policy);
 
   // Verify that a popup that creates a view first and then navigates to a
@@ -466,14 +523,13 @@ TEST_F(RenderViewImplTest, DecideNavigationPolicyForWebUI) {
       GetMainFrame(), popup_request, blink::WebWindowFeatures(), "foo",
       blink::WebNavigationPolicyNewForegroundTab, false);
   RenderViewImpl* new_view = RenderViewImpl::FromWebView(new_web_view);
+  blink::WebFrameClient::NavigationPolicyInfo popup_policy_info(popup_request);
+  popup_policy_info.frame = new_web_view->mainFrame()->toWebLocalFrame();
+  popup_policy_info.extraData = &state;
+  popup_policy_info.navigationType = blink::WebNavigationTypeLinkClicked;
+  popup_policy_info.defaultPolicy = blink::WebNavigationPolicyNewForegroundTab;
   policy = static_cast<RenderFrameImpl*>(new_view->GetMainRenderFrame())->
-      decidePolicyForNavigation(
-          new_web_view->mainFrame()->toWebLocalFrame(),
-          &state,
-          popup_request,
-          blink::WebNavigationTypeLinkClicked,
-          blink::WebNavigationPolicyNewForegroundTab,
-          false);
+      decidePolicyForNavigation(popup_policy_info);
   EXPECT_EQ(blink::WebNavigationPolicyIgnore, policy);
 
   // Clean up after the new view so we don't leak it.
@@ -485,13 +541,16 @@ TEST_F(RenderViewImplTest, DecideNavigationPolicyForWebUI) {
 // already swapped out.  http://crbug.com/93427.
 TEST_F(RenderViewImplTest, SendSwapOutACK) {
   LoadHTML("<div>Page A</div>");
-  int initial_page_id = view()->GetPageId();
+  int initial_page_id = view_page_id();
+
+  // Increment the ref count so that we don't exit when swapping out.
+  RenderProcess::current()->AddRefProcess();
 
   // Respond to a swap out request.
-  view()->main_render_frame()->OnSwapOut();
+  view()->GetMainRenderFrame()->OnSwapOut(kProxyRoutingId);
 
   // Ensure the swap out commits synchronously.
-  EXPECT_NE(initial_page_id, view()->GetPageId());
+  EXPECT_NE(initial_page_id, view_page_id());
 
   // Check for a valid OnSwapOutACK.
   const IPC::Message* msg = render_thread_->sink().GetUniqueMessageMatching(
@@ -501,7 +560,7 @@ TEST_F(RenderViewImplTest, SendSwapOutACK) {
   // It is possible to get another swap out request.  Ensure that we send
   // an ACK, even if we don't have to do anything else.
   render_thread_->sink().ClearMessages();
-  view()->main_render_frame()->OnSwapOut();
+  view()->GetMainRenderFrame()->OnSwapOut(kProxyRoutingId);
   const IPC::Message* msg2 = render_thread_->sink().GetUniqueMessageMatching(
       FrameHostMsg_SwapOut_ACK::ID);
   ASSERT_TRUE(msg2);
@@ -511,11 +570,12 @@ TEST_F(RenderViewImplTest, SendSwapOutACK) {
   FrameMsg_Navigate_Params nav_params;
   nav_params.url = GURL("data:text/html,<div>Page B</div>");
   nav_params.navigation_type = FrameMsg_Navigate_Type::NORMAL;
-  nav_params.transition = PAGE_TRANSITION_TYPED;
+  nav_params.transition = ui::PAGE_TRANSITION_TYPED;
   nav_params.current_history_list_length = 1;
   nav_params.current_history_list_offset = 0;
   nav_params.pending_history_list_offset = 1;
   nav_params.page_id = -1;
+  nav_params.browser_navigation_start = base::TimeTicks::FromInternalValue(1);
   frame()->OnNavigate(nav_params);
   ProcessPendingMessages();
   const IPC::Message* msg3 = render_thread_->sink().GetUniqueMessageMatching(
@@ -537,26 +597,28 @@ TEST_F(RenderViewImplTest, ReloadWhileSwappedOut) {
   const IPC::Message* msg_A = render_thread_->sink().GetUniqueMessageMatching(
       ViewHostMsg_UpdateState::ID);
   ASSERT_TRUE(msg_A);
-  int page_id_A;
-  PageState state_A;
-  ViewHostMsg_UpdateState::Read(msg_A, &page_id_A, &state_A);
+  ViewHostMsg_UpdateState::Param params;
+  ViewHostMsg_UpdateState::Read(msg_A, &params);
+  int page_id_A = params.a;
+  PageState state_A = params.b;
   EXPECT_EQ(1, page_id_A);
   render_thread_->sink().ClearMessages();
 
   // Back to page A (page_id 1) and commit.
   FrameMsg_Navigate_Params params_A;
   params_A.navigation_type = FrameMsg_Navigate_Type::NORMAL;
-  params_A.transition = PAGE_TRANSITION_FORWARD_BACK;
+  params_A.transition = ui::PAGE_TRANSITION_FORWARD_BACK;
   params_A.current_history_list_length = 2;
   params_A.current_history_list_offset = 1;
   params_A.pending_history_list_offset = 0;
   params_A.page_id = 1;
   params_A.page_state = state_A;
+  params_A.browser_navigation_start = base::TimeTicks::FromInternalValue(1);
   frame()->OnNavigate(params_A);
   ProcessPendingMessages();
 
   // Respond to a swap out request.
-  view()->main_render_frame()->OnSwapOut();
+  view()->GetMainRenderFrame()->OnSwapOut(kProxyRoutingId);
 
   // Check for a OnSwapOutACK.
   const IPC::Message* msg = render_thread_->sink().GetUniqueMessageMatching(
@@ -571,12 +633,13 @@ TEST_F(RenderViewImplTest, ReloadWhileSwappedOut) {
   FrameMsg_Navigate_Params nav_params;
   nav_params.url = GURL("data:text/html,<div>Page A</div>");
   nav_params.navigation_type = FrameMsg_Navigate_Type::RELOAD;
-  nav_params.transition = PAGE_TRANSITION_RELOAD;
+  nav_params.transition = ui::PAGE_TRANSITION_RELOAD;
   nav_params.current_history_list_length = 2;
   nav_params.current_history_list_offset = 0;
   nav_params.pending_history_list_offset = 0;
   nav_params.page_id = 1;
   nav_params.page_state = state_A;
+  nav_params.browser_navigation_start = base::TimeTicks::FromInternalValue(1);
   frame()->OnNavigate(nav_params);
   ProcessPendingMessages();
 
@@ -609,9 +672,10 @@ TEST_F(RenderViewImplTest,  DISABLED_LastCommittedUpdateState) {
   const IPC::Message* msg_A = render_thread_->sink().GetUniqueMessageMatching(
       ViewHostMsg_UpdateState::ID);
   ASSERT_TRUE(msg_A);
-  int page_id_A;
-  PageState state_A;
-  ViewHostMsg_UpdateState::Read(msg_A, &page_id_A, &state_A);
+  ViewHostMsg_UpdateState::Param param;
+  ViewHostMsg_UpdateState::Read(msg_A, &param);
+  int page_id_A = param.a;
+  PageState state_A = param.b;
   EXPECT_EQ(1, page_id_A);
   render_thread_->sink().ClearMessages();
 
@@ -623,9 +687,9 @@ TEST_F(RenderViewImplTest,  DISABLED_LastCommittedUpdateState) {
   const IPC::Message* msg_B = render_thread_->sink().GetUniqueMessageMatching(
       ViewHostMsg_UpdateState::ID);
   ASSERT_TRUE(msg_B);
-  int page_id_B;
-  PageState state_B;
-  ViewHostMsg_UpdateState::Read(msg_B, &page_id_B, &state_B);
+  ViewHostMsg_UpdateState::Read(msg_B, &param);
+  int page_id_B = param.a;
+  PageState state_B = param.b;
   EXPECT_EQ(2, page_id_B);
   EXPECT_NE(state_A, state_B);
   render_thread_->sink().ClearMessages();
@@ -638,9 +702,9 @@ TEST_F(RenderViewImplTest,  DISABLED_LastCommittedUpdateState) {
   const IPC::Message* msg_C = render_thread_->sink().GetUniqueMessageMatching(
       ViewHostMsg_UpdateState::ID);
   ASSERT_TRUE(msg_C);
-  int page_id_C;
-  PageState state_C;
-  ViewHostMsg_UpdateState::Read(msg_C, &page_id_C, &state_C);
+  ViewHostMsg_UpdateState::Read(msg_C, &param);
+  int page_id_C = param.a;
+  PageState state_C = param.b;
   EXPECT_EQ(3, page_id_C);
   EXPECT_NE(state_B, state_C);
   render_thread_->sink().ClearMessages();
@@ -648,12 +712,13 @@ TEST_F(RenderViewImplTest,  DISABLED_LastCommittedUpdateState) {
   // Go back to C and commit, preparing for our real test.
   FrameMsg_Navigate_Params params_C;
   params_C.navigation_type = FrameMsg_Navigate_Type::NORMAL;
-  params_C.transition = PAGE_TRANSITION_FORWARD_BACK;
+  params_C.transition = ui::PAGE_TRANSITION_FORWARD_BACK;
   params_C.current_history_list_length = 4;
   params_C.current_history_list_offset = 3;
   params_C.pending_history_list_offset = 2;
   params_C.page_id = 3;
   params_C.page_state = state_C;
+  params_C.browser_navigation_start = base::TimeTicks::FromInternalValue(1);
   frame()->OnNavigate(params_C);
   ProcessPendingMessages();
   render_thread_->sink().ClearMessages();
@@ -665,23 +730,25 @@ TEST_F(RenderViewImplTest,  DISABLED_LastCommittedUpdateState) {
   // Back to page B (page_id 2), without committing.
   FrameMsg_Navigate_Params params_B;
   params_B.navigation_type = FrameMsg_Navigate_Type::NORMAL;
-  params_B.transition = PAGE_TRANSITION_FORWARD_BACK;
+  params_B.transition = ui::PAGE_TRANSITION_FORWARD_BACK;
   params_B.current_history_list_length = 4;
   params_B.current_history_list_offset = 2;
   params_B.pending_history_list_offset = 1;
   params_B.page_id = 2;
   params_B.page_state = state_B;
+  params_B.browser_navigation_start = base::TimeTicks::FromInternalValue(1);
   frame()->OnNavigate(params_B);
 
   // Back to page A (page_id 1) and commit.
   FrameMsg_Navigate_Params params;
   params.navigation_type = FrameMsg_Navigate_Type::NORMAL;
-  params.transition = PAGE_TRANSITION_FORWARD_BACK;
+  params.transition = ui::PAGE_TRANSITION_FORWARD_BACK;
   params_B.current_history_list_length = 4;
   params_B.current_history_list_offset = 2;
   params_B.pending_history_list_offset = 0;
   params.page_id = 1;
   params.page_state = state_A;
+  params.browser_navigation_start = base::TimeTicks::FromInternalValue(1);
   frame()->OnNavigate(params);
   ProcessPendingMessages();
 
@@ -690,9 +757,9 @@ TEST_F(RenderViewImplTest,  DISABLED_LastCommittedUpdateState) {
   const IPC::Message* msg = render_thread_->sink().GetUniqueMessageMatching(
       ViewHostMsg_UpdateState::ID);
   ASSERT_TRUE(msg);
-  int page_id;
-  PageState state;
-  ViewHostMsg_UpdateState::Read(msg, &page_id, &state);
+  ViewHostMsg_UpdateState::Read(msg, &param);
+  int page_id = param.a;
+  PageState state = param.b;
   EXPECT_EQ(page_id_C, page_id);
   EXPECT_NE(state_A, state);
   EXPECT_NE(state_B, state);
@@ -720,21 +787,23 @@ TEST_F(RenderViewImplTest, StaleNavigationsIgnored) {
   const IPC::Message* msg_A = render_thread_->sink().GetUniqueMessageMatching(
       ViewHostMsg_UpdateState::ID);
   ASSERT_TRUE(msg_A);
-  int page_id_A;
-  PageState state_A;
-  ViewHostMsg_UpdateState::Read(msg_A, &page_id_A, &state_A);
+  ViewHostMsg_UpdateState::Param param;
+  ViewHostMsg_UpdateState::Read(msg_A, &param);
+  int page_id_A = param.a;
+  PageState state_A = param.b;
   EXPECT_EQ(1, page_id_A);
   render_thread_->sink().ClearMessages();
 
   // Back to page A (page_id 1) and commit.
   FrameMsg_Navigate_Params params_A;
   params_A.navigation_type = FrameMsg_Navigate_Type::NORMAL;
-  params_A.transition = PAGE_TRANSITION_FORWARD_BACK;
+  params_A.transition = ui::PAGE_TRANSITION_FORWARD_BACK;
   params_A.current_history_list_length = 2;
   params_A.current_history_list_offset = 1;
   params_A.pending_history_list_offset = 0;
   params_A.page_id = 1;
   params_A.page_state = state_A;
+  params_A.browser_navigation_start = base::TimeTicks::FromInternalValue(1);
   frame()->OnNavigate(params_A);
   ProcessPendingMessages();
 
@@ -747,12 +816,13 @@ TEST_F(RenderViewImplTest, StaleNavigationsIgnored) {
   // The browser then sends a stale navigation to B, which should be ignored.
   FrameMsg_Navigate_Params params_B;
   params_B.navigation_type = FrameMsg_Navigate_Type::NORMAL;
-  params_B.transition = PAGE_TRANSITION_FORWARD_BACK;
+  params_B.transition = ui::PAGE_TRANSITION_FORWARD_BACK;
   params_B.current_history_list_length = 2;
   params_B.current_history_list_offset = 0;
   params_B.pending_history_list_offset = 1;
   params_B.page_id = 2;
   params_B.page_state = state_A;  // Doesn't matter, just has to be present.
+  params_B.browser_navigation_start = base::TimeTicks::FromInternalValue(1);
   frame()->OnNavigate(params_B);
 
   // State should be unchanged.
@@ -785,9 +855,10 @@ TEST_F(RenderViewImplTest, DontIgnoreBackAfterNavEntryLimit) {
   const IPC::Message* msg_A = render_thread_->sink().GetUniqueMessageMatching(
       ViewHostMsg_UpdateState::ID);
   ASSERT_TRUE(msg_A);
-  int page_id_A;
-  PageState state_A;
-  ViewHostMsg_UpdateState::Read(msg_A, &page_id_A, &state_A);
+  ViewHostMsg_UpdateState::Param param;
+  ViewHostMsg_UpdateState::Read(msg_A, &param);
+  int page_id_A = param.a;
+  PageState state_A = param.b;
   EXPECT_EQ(1, page_id_A);
   render_thread_->sink().ClearMessages();
 
@@ -802,9 +873,9 @@ TEST_F(RenderViewImplTest, DontIgnoreBackAfterNavEntryLimit) {
   const IPC::Message* msg_B = render_thread_->sink().GetUniqueMessageMatching(
       ViewHostMsg_UpdateState::ID);
   ASSERT_TRUE(msg_B);
-  int page_id_B;
-  PageState state_B;
-  ViewHostMsg_UpdateState::Read(msg_B, &page_id_B, &state_B);
+  ViewHostMsg_UpdateState::Read(msg_B, &param);
+  int page_id_B = param.a;
+  PageState state_B = param.b;
   EXPECT_EQ(2, page_id_B);
   render_thread_->sink().ClearMessages();
 
@@ -813,12 +884,13 @@ TEST_F(RenderViewImplTest, DontIgnoreBackAfterNavEntryLimit) {
   // Ensure that going back to page B (page_id 2) at offset 0 is successful.
   FrameMsg_Navigate_Params params_B;
   params_B.navigation_type = FrameMsg_Navigate_Type::NORMAL;
-  params_B.transition = PAGE_TRANSITION_FORWARD_BACK;
+  params_B.transition = ui::PAGE_TRANSITION_FORWARD_BACK;
   params_B.current_history_list_length = 2;
   params_B.current_history_list_offset = 1;
   params_B.pending_history_list_offset = 0;
   params_B.page_id = 2;
   params_B.page_state = state_B;
+  params_B.browser_navigation_start = base::TimeTicks::FromInternalValue(1);
   frame()->OnNavigate(params_B);
   ProcessPendingMessages();
 
@@ -895,13 +967,11 @@ TEST_F(RenderViewImplTest, OnImeTypeChanged) {
     const IPC::Message* msg = render_thread_->sink().GetMessageAt(0);
     EXPECT_TRUE(msg != NULL);
     EXPECT_EQ(ViewHostMsg_TextInputTypeChanged::ID, msg->type());
-    ui::TextInputType type;
-    bool can_compose_inline = false;
-    ui::TextInputMode input_mode = ui::TEXT_INPUT_MODE_DEFAULT;
-    ViewHostMsg_TextInputTypeChanged::Read(msg,
-                                           &type,
-                                           &input_mode,
-                                           &can_compose_inline);
+    ViewHostMsg_TextInputTypeChanged::Param params;
+    ViewHostMsg_TextInputTypeChanged::Read(msg, &params);
+    ui::TextInputType type = params.a;
+    ui::TextInputMode input_mode = params.b;
+    bool can_compose_inline = params.c;
     EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, type);
     EXPECT_EQ(true, can_compose_inline);
 
@@ -917,10 +987,9 @@ TEST_F(RenderViewImplTest, OnImeTypeChanged) {
     msg = render_thread_->sink().GetMessageAt(0);
     EXPECT_TRUE(msg != NULL);
     EXPECT_EQ(ViewHostMsg_TextInputTypeChanged::ID, msg->type());
-    ViewHostMsg_TextInputTypeChanged::Read(msg,
-                                           &type,
-                                           &input_mode,
-                                           &can_compose_inline);
+    ViewHostMsg_TextInputTypeChanged::Read(msg, & params);
+    type = params.a;
+    input_mode = params.b;
     EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, type);
 
     for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kInputModeTestCases); i++) {
@@ -940,10 +1009,9 @@ TEST_F(RenderViewImplTest, OnImeTypeChanged) {
       const IPC::Message* msg = render_thread_->sink().GetMessageAt(0);
       EXPECT_TRUE(msg != NULL);
       EXPECT_EQ(ViewHostMsg_TextInputTypeChanged::ID, msg->type());
-      ViewHostMsg_TextInputTypeChanged::Read(msg,
-                                            &type,
-                                            &input_mode,
-                                            &can_compose_inline);
+      ViewHostMsg_TextInputTypeChanged::Read(msg, & params);
+      type = params.a;
+      input_mode = params.b;
       EXPECT_EQ(test_case->expected_mode, input_mode);
     }
   }
@@ -1532,10 +1600,11 @@ TEST_F(RenderViewImplTest, DISABLED_DidFailProvisionalLoadWithErrorForError) {
   params.page_id = -1;
   params.navigation_type = FrameMsg_Navigate_Type::NORMAL;
   params.url = GURL("data:text/html,test data");
+  params.browser_navigation_start = base::TimeTicks::FromInternalValue(1);
   frame()->OnNavigate(params);
 
   // An error occurred.
-  view()->main_render_frame()->didFailProvisionalLoad(web_frame, error);
+  view()->GetMainRenderFrame()->didFailProvisionalLoad(web_frame, error);
   // Frame should exit view-source mode.
   EXPECT_FALSE(web_frame->isViewSourceModeEnabled());
 }
@@ -1554,10 +1623,11 @@ TEST_F(RenderViewImplTest, DidFailProvisionalLoadWithErrorForCancellation) {
   params.page_id = -1;
   params.navigation_type = FrameMsg_Navigate_Type::NORMAL;
   params.url = GURL("data:text/html,test data");
+  params.browser_navigation_start = base::TimeTicks::FromInternalValue(1);
   frame()->OnNavigate(params);
 
   // A cancellation occurred.
-  view()->main_render_frame()->didFailProvisionalLoad(web_frame, error);
+  view()->GetMainRenderFrame()->didFailProvisionalLoad(web_frame, error);
   // Frame should stay in view-source mode.
   EXPECT_TRUE(web_frame->isViewSourceModeEnabled());
 }
@@ -1810,6 +1880,9 @@ TEST_F(RenderViewImplTest, TestBackForward) {
   EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_b, &was_page_b));
   EXPECT_EQ(1, was_page_b);
 
+  PageState back_state =
+      HistoryEntryToPageState(view()->history_controller()->GetCurrentEntry());
+
   LoadHTML("<div id=pagename>Page C</div>");
   int was_page_c = -1;
   base::string16 check_page_c =
@@ -1820,17 +1893,18 @@ TEST_F(RenderViewImplTest, TestBackForward) {
 
   PageState forward_state =
       HistoryEntryToPageState(view()->history_controller()->GetCurrentEntry());
-  GoBack(HistoryEntryToPageState(
-      view()->history_controller()->GetPreviousEntry()));
+  GoBack(back_state);
   EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_b, &was_page_b));
   EXPECT_EQ(1, was_page_b);
 
+  PageState back_state2 =
+      HistoryEntryToPageState(view()->history_controller()->GetCurrentEntry());
+
   GoForward(forward_state);
   EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_c, &was_page_c));
   EXPECT_EQ(1, was_page_c);
 
-  GoBack(HistoryEntryToPageState(
-      view()->history_controller()->GetPreviousEntry()));
+  GoBack(back_state2);
   EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(check_page_b, &was_page_b));
   EXPECT_EQ(1, was_page_b);
 
@@ -1930,6 +2004,7 @@ TEST_F(RenderViewImplTest, ZoomLimit) {
   FrameMsg_Navigate_Params params;
   params.page_id = -1;
   params.navigation_type = FrameMsg_Navigate_Type::NORMAL;
+  params.browser_navigation_start = base::TimeTicks::FromInternalValue(1);
 
   // Verifies navigation to a URL with preset zoom level indeed sets the level.
   // Regression test for http://crbug.com/139559, where the level was not
@@ -2008,12 +2083,13 @@ TEST_F(RenderViewImplTest, NavigateFrame) {
   FrameMsg_Navigate_Params nav_params;
   nav_params.url = GURL("data:text/html,world");
   nav_params.navigation_type = FrameMsg_Navigate_Type::NORMAL;
-  nav_params.transition = PAGE_TRANSITION_TYPED;
+  nav_params.transition = ui::PAGE_TRANSITION_TYPED;
   nav_params.current_history_list_length = 1;
   nav_params.current_history_list_offset = 0;
   nav_params.pending_history_list_offset = 1;
   nav_params.page_id = -1;
   nav_params.frame_to_navigate = "frame";
+  nav_params.browser_navigation_start = base::TimeTicks::FromInternalValue(1);
   frame()->OnNavigate(nav_params);
   FrameLoadWaiter(
       RenderFrame::FromWebFrame(frame()->GetWebFrame()->firstChild())).Wait();
@@ -2133,10 +2209,11 @@ TEST_F(SuppressErrorPageTest, MAYBE_Suppresses) {
   params.page_id = -1;
   params.navigation_type = FrameMsg_Navigate_Type::NORMAL;
   params.url = GURL("data:text/html,test data");
+  params.browser_navigation_start = base::TimeTicks::FromInternalValue(1);
   frame()->OnNavigate(params);
 
   // An error occurred.
-  view()->main_render_frame()->didFailProvisionalLoad(web_frame, error);
+  view()->GetMainRenderFrame()->didFailProvisionalLoad(web_frame, error);
   const int kMaxOutputCharacters = 22;
   EXPECT_EQ("",
             base::UTF16ToASCII(web_frame->contentAsText(kMaxOutputCharacters)));
@@ -2162,10 +2239,11 @@ TEST_F(SuppressErrorPageTest, MAYBE_DoesNotSuppress) {
   params.page_id = -1;
   params.navigation_type = FrameMsg_Navigate_Type::NORMAL;
   params.url = GURL("data:text/html,test data");
+  params.browser_navigation_start = base::TimeTicks::FromInternalValue(1);
   frame()->OnNavigate(params);
 
   // An error occurred.
-  view()->main_render_frame()->didFailProvisionalLoad(web_frame, error);
+  view()->GetMainRenderFrame()->didFailProvisionalLoad(web_frame, error);
   // The error page itself is loaded asynchronously.
   FrameLoadWaiter(frame()).Wait();
   const int kMaxOutputCharacters = 22;
@@ -2233,40 +2311,6 @@ TEST_F(RenderViewImplTest, SendFaviconURLUpdateEvent) {
       ViewHostMsg_UpdateFaviconURL::ID));
 }
 
-// Test progress tracker messages.
-TEST_F(RenderViewImplTest, SendProgressCompletionUpdates) {
-  std::string data_url_string = "data:text/html,<body>placeholder</body>";
-  GURL url(data_url_string);
-  GetMainFrame()->loadRequest(blink::WebURLRequest(url));
-
-  EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching(
-      FrameHostMsg_DidStartLoading::ID));
-
-  // The load started, we should receive a start notification and a progress
-  // update with the minimum progress.
-  const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
-      ViewHostMsg_DidChangeLoadProgress::ID);
-  EXPECT_TRUE(message);
-  Tuple1<double> progress_value;
-  ViewHostMsg_DidChangeLoadProgress::Read(message, &progress_value);
-  EXPECT_EQ(0.1, progress_value.a);
-  render_thread_->sink().ClearMessages();
-
-  FrameLoadWaiter(frame()).Wait();
-
-  // The data url has loaded, so we should see a progress change to 1.0 (done)
-  // and a stop notification.
-  message = render_thread_->sink().GetFirstMessageMatching(
-      ViewHostMsg_DidChangeLoadProgress::ID);
-  EXPECT_TRUE(message);
-  ViewHostMsg_DidChangeLoadProgress::Read(message, &progress_value);
-  EXPECT_EQ(1.0, progress_value.a);
-
-  EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching(
-      FrameHostMsg_DidStopLoading::ID));
-  render_thread_->sink().ClearMessages();
-}
-
 TEST_F(RenderViewImplTest, FocusElementCallsFocusedNodeChanged) {
   LoadHTML("<input id='test1' value='hello1'></input>"
            "<input id='test2' value='hello2'></input>");
@@ -2331,7 +2375,7 @@ TEST_F(RenderViewImplTest, ServiceWorkerNetworkProviderSetup) {
   // 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.setTargetType(blink::WebURLRequest::TargetIsSubresource);
+  request.setRequestContext(blink::WebURLRequest::RequestContextSubresource);
   blink::WebURLResponse redirect_response;
   frame()->willSendRequest(GetMainFrame(), 0, request, redirect_response);
   extra_data = static_cast<RequestExtraData*>(request.extraData());
@@ -2341,30 +2385,106 @@ TEST_F(RenderViewImplTest, ServiceWorkerNetworkProviderSetup) {
 }
 
 TEST_F(RenderViewImplTest, OnSetAccessibilityMode) {
-  ASSERT_EQ(AccessibilityModeOff, view()->accessibility_mode());
-  ASSERT_EQ((RendererAccessibility*) NULL, view()->renderer_accessibility());
+  ASSERT_EQ(AccessibilityModeOff, frame()->accessibility_mode());
+  ASSERT_EQ((RendererAccessibility*) NULL, frame()->renderer_accessibility());
 
-  view()->OnSetAccessibilityMode(AccessibilityModeTreeOnly);
-  ASSERT_EQ(AccessibilityModeTreeOnly, view()->accessibility_mode());
-  ASSERT_NE((RendererAccessibility*) NULL, view()->renderer_accessibility());
+  frame()->OnSetAccessibilityMode(AccessibilityModeTreeOnly);
+  ASSERT_EQ(AccessibilityModeTreeOnly, frame()->accessibility_mode());
+  ASSERT_NE((RendererAccessibility*) NULL, frame()->renderer_accessibility());
   ASSERT_EQ(RendererAccessibilityTypeComplete,
-            view()->renderer_accessibility()->GetType());
+            frame()->renderer_accessibility()->GetType());
 
-  view()->OnSetAccessibilityMode(AccessibilityModeOff);
-  ASSERT_EQ(AccessibilityModeOff, view()->accessibility_mode());
-  ASSERT_EQ((RendererAccessibility*) NULL, view()->renderer_accessibility());
+  frame()->OnSetAccessibilityMode(AccessibilityModeOff);
+  ASSERT_EQ(AccessibilityModeOff, frame()->accessibility_mode());
+  ASSERT_EQ((RendererAccessibility*) NULL, frame()->renderer_accessibility());
 
-  view()->OnSetAccessibilityMode(AccessibilityModeComplete);
-  ASSERT_EQ(AccessibilityModeComplete, view()->accessibility_mode());
-  ASSERT_NE((RendererAccessibility*) NULL, view()->renderer_accessibility());
+  frame()->OnSetAccessibilityMode(AccessibilityModeComplete);
+  ASSERT_EQ(AccessibilityModeComplete, frame()->accessibility_mode());
+  ASSERT_NE((RendererAccessibility*) NULL, frame()->renderer_accessibility());
   ASSERT_EQ(RendererAccessibilityTypeComplete,
-            view()->renderer_accessibility()->GetType());
+            frame()->renderer_accessibility()->GetType());
 
-  view()->OnSetAccessibilityMode(AccessibilityModeEditableTextOnly);
-  ASSERT_EQ(AccessibilityModeEditableTextOnly, view()->accessibility_mode());
-  ASSERT_NE((RendererAccessibility*) NULL, view()->renderer_accessibility());
+  frame()->OnSetAccessibilityMode(AccessibilityModeEditableTextOnly);
+  ASSERT_EQ(AccessibilityModeEditableTextOnly, frame()->accessibility_mode());
+  ASSERT_NE((RendererAccessibility*) NULL, frame()->renderer_accessibility());
   ASSERT_EQ(RendererAccessibilityTypeFocusOnly,
-            view()->renderer_accessibility()->GetType());
+            frame()->renderer_accessibility()->GetType());
+}
+
+TEST_F(RenderViewImplTest, ScreenMetricsEmulation) {
+  LoadHTML("<body style='min-height:1000px;'></body>");
+
+  blink::WebDeviceEmulationParams params;
+  base::string16 get_width = base::ASCIIToUTF16("Number(window.innerWidth)");
+  base::string16 get_height = base::ASCIIToUTF16("Number(window.innerHeight)");
+  int width, height;
+
+  params.viewSize.width = 327;
+  params.viewSize.height = 415;
+  view()->EnableScreenMetricsEmulation(params);
+  EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(get_width, &width));
+  EXPECT_EQ(params.viewSize.width, width);
+  EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(get_height, &height));
+  EXPECT_EQ(params.viewSize.height, height);
+
+  params.viewSize.width = 1005;
+  params.viewSize.height = 1102;
+  view()->EnableScreenMetricsEmulation(params);
+  EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(get_width, &width));
+  EXPECT_EQ(params.viewSize.width, width);
+  EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(get_height, &height));
+  EXPECT_EQ(params.viewSize.height, height);
+
+  view()->DisableScreenMetricsEmulation();
+
+  view()->EnableScreenMetricsEmulation(params);
+  // Don't disable here to test that emulation is being shutdown properly.
+}
+
+// Sanity checks 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, NavigationStartOverride) {
+  // Verify that a navigation that claims to have started at the earliest
+  // possible TimeTicks is indeed reported as one that started before
+  // OnNavigate() is called.
+  base::Time before_navigation = base::Time::Now();
+  FrameMsg_Navigate_Params early_nav_params;
+  early_nav_params.url = GURL("data:text/html,<div>Page</div>");
+  early_nav_params.navigation_type = FrameMsg_Navigate_Type::NORMAL;
+  early_nav_params.transition = ui::PAGE_TRANSITION_TYPED;
+  early_nav_params.page_id = -1;
+  early_nav_params.is_post = true;
+  early_nav_params.browser_navigation_start =
+      base::TimeTicks::FromInternalValue(1);
+
+  frame()->OnNavigate(early_nav_params);
+  ProcessPendingMessages();
+
+  base::Time early_nav_reported_start =
+      base::Time::FromDoubleT(GetMainFrame()->performance().navigationStart());
+  EXPECT_LT(early_nav_reported_start, before_navigation);
+
+  // 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().
+  FrameMsg_Navigate_Params late_nav_params;
+  late_nav_params.url = GURL("data:text/html,<div>Another page</div>");
+  late_nav_params.navigation_type = FrameMsg_Navigate_Type::NORMAL;
+  late_nav_params.transition = ui::PAGE_TRANSITION_TYPED;
+  late_nav_params.page_id = -1;
+  late_nav_params.is_post = true;
+  late_nav_params.browser_navigation_start =
+      base::TimeTicks::Now() + base::TimeDelta::FromDays(42);
+
+  frame()->OnNavigate(late_nav_params);
+  ProcessPendingMessages();
+  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);
 }
 
 }  // namespace content