diff --git a/BUILD.gn b/BUILD.gn
index 5c26c72..b804a562 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -159,13 +159,28 @@
 
   if (!is_ios) {
     deps += [
+      "//cc:cc_unittests",
+      "//components/policy:policy_templates",
+      "//content/shell:content_shell",
+      "//content/test:content_browsertests",
+      "//content/test:content_perftests",
+      "//content/test:content_unittests",
+      "//gpu:gpu_unittests",
+      "//gpu/ipc/service:gpu_ipc_service_unittests",
+      "//ipc:ipc_tests",
       "//media:media_unittests",
+      "//media/midi:midi_unittests",
+      "//media/mojo:media_mojo_unittests",
       "//mojo",
       "//mojo/common:mojo_common_unittests",
       "//mojo/edk/system:mojo_system_unittests",
       "//mojo/edk/test:mojo_public_bindings_unittests",
       "//mojo/edk/test:mojo_public_system_unittests",
+      "//net:net_perftests",
+      "//third_party/WebKit/Source/controller:webkit_unit_tests",
+      "//third_party/WebKit/Source/platform/wtf:wtf_unittests",
       "//ui/gl:gl_unittests",
+      "//url/ipc:url_ipc_unittests",
     ]
   }
 
@@ -178,38 +193,19 @@
 
   if (!is_ios && !is_fuchsia) {
     deps += [
-      "//cc:cc_unittests",
       "//chrome/test:telemetry_perf_unittests",
       "//chrome/test:unit_tests",
       "//components:components_browsertests",
-      "//components/policy:policy_templates",
       "//components/viz:viz_perftests",
       "//components/viz:viz_unittests",
       "//components/viz/common:viz_benchmark",
-      "//content/shell:content_shell",
-      "//content/test:content_browsertests",
-      "//content/test:content_perftests",
-      "//content/test:content_unittests",
       "//device:device_unittests",
       "//google_apis/gcm:mcs_probe",
-      "//gpu:gpu_unittests",
-      "//gpu/ipc/service:gpu_ipc_service_unittests",
-      "//ipc:ipc_tests",
       "//media/capture:capture_unittests",
       "//media/cast:cast_unittests",
-      "//media/midi:midi_unittests",
-      "//media/mojo:media_mojo_unittests",
-      "//mojo",
-      "//mojo/common:mojo_common_unittests",
-      "//mojo/edk/system:mojo_system_unittests",
-      "//mojo/edk/test:mojo_public_bindings_unittests",
-      "//mojo/edk/test:mojo_public_system_unittests",
-      "//net:net_perftests",
       "//storage:storage_unittests",
-      "//third_party/WebKit/Source/controller:webkit_unit_tests",
       "//third_party/WebKit/Source/platform:blink_platform_unittests",
       "//third_party/WebKit/Source/platform/heap:blink_heap_unittests",
-      "//third_party/WebKit/Source/platform/wtf:wtf_unittests",
       "//third_party/angle/src/tests:angle_end2end_tests",
       "//third_party/angle/src/tests:angle_unittests",
       "//third_party/angle/src/tests:angle_white_box_tests",
@@ -220,7 +216,6 @@
       "//ui/events:events_unittests",
       "//ui/latency:latency_unittests",
       "//ui/touch_selection:ui_touch_selection_unittests",
-      "//url/ipc:url_ipc_unittests",
       "//v8:gn_all",
     ]
   } else if (is_ios) {
@@ -263,9 +258,15 @@
     deps += [
       "//ui/ozone",
       "//ui/ozone:ozone_unittests",
-      "//ui/ozone/demo",
-      "//ui/ozone/gl:ozone_gl_unittests",
     ]
+
+    # TODO(crbug.com/766360): These require a working GL implementation.
+    if (!is_fuchsia) {
+      deps += [
+        "//ui/ozone/demo",
+        "//ui/ozone/gl:ozone_gl_unittests",
+      ]
+    }
   }
 
   if (use_x11 || ozone_platform_x11) {
@@ -734,7 +735,11 @@
   }
 
   if (is_fuchsia) {
-    deps += [ "//headless" ]
+    deps += [
+      "//headless",
+      "//headless:headless_shell",
+      "//headless:headless_tests",
+    ]
   }
 }
 
diff --git a/DEPS b/DEPS
index d1a1aae5..48b461da1 100644
--- a/DEPS
+++ b/DEPS
@@ -78,7 +78,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': 'b88605f7468d01c269bda1d4d79bbd4f3d38e8a8',
+  'v8_revision': '7af7216b70af5740ca153946047ea00ed593e0c9',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -98,7 +98,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': '12ec6760afd92b63d185854008a55762fe39f866',
+  'pdfium_revision': 'c45271e053c8c458cefa4ccf847c85b7d1df3f09',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling openmax_dl
   # and whatever else without interference from each other.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeWindow.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeWindow.java
index 8567a5c..6fe41be 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeWindow.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeWindow.java
@@ -10,6 +10,7 @@
 import org.chromium.chrome.browser.infobar.SimpleConfirmInfoBarBuilder;
 import org.chromium.chrome.browser.metrics.WebApkUma;
 import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.webapps.WebApkActivity;
 import org.chromium.ui.base.ActivityWindowAndroid;
 
 /**
@@ -28,7 +29,8 @@
     @Override
     protected void logUMAOnRequestPermissionDenied(String permission) {
         Activity activity = getActivity().get();
-        if (activity != null && ((ChromeActivity) activity).didFinishNativeInitialization()) {
+        if (activity instanceof WebApkActivity
+                && ((ChromeActivity) activity).didFinishNativeInitialization()) {
             WebApkUma.recordAndroidRuntimePermissionDeniedInWebApk(new String[] {permission});
         }
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/SurveyInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/SurveyInfoBar.java
index 5ab780e1..2506cf6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/SurveyInfoBar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/SurveyInfoBar.java
@@ -101,7 +101,7 @@
 
                 SurveyController.getInstance().showSurveyIfAvailable(
                         tab.getActivity(), mSiteId, mShowAsBottomSheet, mDisplayLogoResId);
-                onCloseButtonClicked();
+                closeInfoBar();
                 mClicked = true;
             }
         };
@@ -118,7 +118,8 @@
     }
 
     /**
-     * Closes the infobar without calling the {@link SurveyInfoBarDelegate}'s onSurveyInfoBarClosed.
+     * Closes the infobar without calling the {@link SurveyInfoBarDelegate}'s
+     * onSurveyInfoBarCloseButtonClicked.
      */
     private void closeInfoBar() {
         // TODO(mdjones): add a proper close method to programatically close the infobar.
@@ -127,7 +128,7 @@
 
     @Override
     public void onCloseButtonClicked() {
-        mDelegate.onSurveyInfoBarClosed();
+        mDelegate.onSurveyInfoBarCloseButtonClicked();
         super.onCloseButtonClicked();
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/SurveyInfoBarDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/SurveyInfoBarDelegate.java
index acd9ef8..d24b423 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/SurveyInfoBarDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/SurveyInfoBarDelegate.java
@@ -19,9 +19,9 @@
     void onSurveyInfoBarTabInteractabilityChanged(boolean isInteractable);
 
     /**
-     * Notified when the survey infobar is closed.
+     * Notified when the survey infobar's close button is clicked.
      */
-    void onSurveyInfoBarClosed();
+    void onSurveyInfoBarCloseButtonClicked();
 
     /**
      * Notified when the survey is triggered via the infobar.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/WebApkUma.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/WebApkUma.java
index 461dc02..05ab619 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/WebApkUma.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/WebApkUma.java
@@ -178,7 +178,7 @@
      * Chrome does not have that permission.
      */
     public static void recordAndroidRuntimePermissionDeniedInWebApk(final String[] permissions) {
-        recordPermissionUma("WebApk.Permission.ChromePermissionDenied", permissions);
+        recordPermissionUma("WebApk.Permission.ChromePermissionDenied2", permissions);
     }
 
     private static void recordPermissionUma(String permissionUmaName, final String[] permissions) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeHomeSurveyController.java b/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeHomeSurveyController.java
index b73d55dd..4b3619e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeHomeSurveyController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeHomeSurveyController.java
@@ -337,13 +337,15 @@
             }
 
             @Override
-            public void onSurveyInfoBarClosed() {
+            public void onSurveyInfoBarCloseButtonClicked() {
+                RecordUserAction.record("Android.ChromeHome.ClickedSurveyInfoBarCloseButton");
                 recordInfoBarDisplayed();
             }
 
             @Override
             public void onSurveyTriggered() {
                 RecordUserAction.record("Android.ChromeHome.AcceptedSurvey");
+                recordInfoBarDisplayed();
             }
 
             @Override
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 1d8e30c..39e13da 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -1083,6 +1083,8 @@
     "login/ui/login_display_host_views.h",
     "login/ui/login_display_host_webui.cc",
     "login/ui/login_display_host_webui.h",
+    "login/ui/login_display_webui.cc",
+    "login/ui/login_display_webui.h",
     "login/ui/login_feedback.cc",
     "login/ui/login_feedback.h",
     "login/ui/login_web_dialog.cc",
@@ -1100,8 +1102,6 @@
     "login/ui/views/user_board_view.h",
     "login/ui/web_contents_forced_title.cc",
     "login/ui/web_contents_forced_title.h",
-    "login/ui/webui_login_display.cc",
-    "login/ui/webui_login_display.h",
     "login/ui/webui_login_view.cc",
     "login/ui/webui_login_view.h",
     "login/user_flow.cc",
diff --git a/chrome/browser/chromeos/login/lock/webui_screen_locker.cc b/chrome/browser/chromeos/login/lock/webui_screen_locker.cc
index 124f663..792baec 100644
--- a/chrome/browser/chromeos/login/lock/webui_screen_locker.cc
+++ b/chrome/browser/chromeos/login/lock/webui_screen_locker.cc
@@ -17,9 +17,9 @@
 #include "chrome/browser/chromeos/login/lock/screen_locker.h"
 #include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_factory.h"
 #include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_storage.h"
+#include "chrome/browser/chromeos/login/ui/login_display_webui.h"
 #include "chrome/browser/chromeos/login/ui/preloaded_web_view.h"
 #include "chrome/browser/chromeos/login/ui/preloaded_web_view_factory.h"
-#include "chrome/browser/chromeos/login/ui/webui_login_display.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/ui/ash/ash_util.h"
 #include "chrome/browser/ui/ash/session_controller_client.h"
@@ -169,7 +169,7 @@
   signin_screen_controller_.reset(
       new SignInScreenController(GetOobeUI(), this));
 
-  login_display_.reset(new WebUILoginDisplay(this));
+  login_display_.reset(new LoginDisplayWebUI(this));
   login_display_->set_parent_window(GetNativeWindow());
   login_display_->Init(screen_locker_->users(), false, true, false);
 
diff --git a/chrome/browser/chromeos/login/lock/webui_screen_locker.h b/chrome/browser/chromeos/login/lock/webui_screen_locker.h
index 363af938..19dce9e 100644
--- a/chrome/browser/chromeos/login/lock/webui_screen_locker.h
+++ b/chrome/browser/chromeos/login/lock/webui_screen_locker.h
@@ -32,7 +32,7 @@
 namespace chromeos {
 
 class ScreenLocker;
-class WebUILoginDisplay;
+class LoginDisplayWebUI;
 
 namespace login {
 class NetworkStateHelper;
@@ -154,7 +154,7 @@
   std::unique_ptr<SignInScreenController> signin_screen_controller_;
 
   // Login UI implementation instance.
-  std::unique_ptr<WebUILoginDisplay> login_display_;
+  std::unique_ptr<LoginDisplayWebUI> login_display_;
 
   // Tracks when the lock window is displayed and ready.
   bool lock_ready_ = false;
diff --git a/chrome/browser/chromeos/login/login_utils_browsertest.cc b/chrome/browser/chromeos/login/login_utils_browsertest.cc
index c4e6043..49fd917 100644
--- a/chrome/browser/chromeos/login/login_utils_browsertest.cc
+++ b/chrome/browser/chromeos/login/login_utils_browsertest.cc
@@ -14,7 +14,7 @@
 #include "chrome/browser/chromeos/ash_config.h"
 #include "chrome/browser/chromeos/login/existing_user_controller.h"
 #include "chrome/browser/chromeos/login/test/oobe_base_test.h"
-#include "chrome/browser/chromeos/login/ui/webui_login_display.h"
+#include "chrome/browser/chromeos/login/ui/login_display_webui.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
 #include "chrome/common/chrome_switches.h"
@@ -66,8 +66,8 @@
     ExistingUserController* controller =
         ExistingUserController::current_controller();
     ASSERT_TRUE(controller);
-    WebUILoginDisplay* login_display =
-        static_cast<WebUILoginDisplay*>(controller->login_display());
+    LoginDisplayWebUI* login_display =
+        static_cast<LoginDisplayWebUI*>(controller->login_display());
     ASSERT_TRUE(login_display);
 
     login_display->ShowSigninScreenForCreds(username, "password");
diff --git a/chrome/browser/chromeos/login/oobe_browsertest.cc b/chrome/browser/chromeos/login/oobe_browsertest.cc
index cf2a964..473f060 100644
--- a/chrome/browser/chromeos/login/oobe_browsertest.cc
+++ b/chrome/browser/chromeos/login/oobe_browsertest.cc
@@ -12,7 +12,7 @@
 #include "chrome/browser/chromeos/login/test/oobe_base_test.h"
 #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host_webui.h"
-#include "chrome/browser/chromeos/login/ui/webui_login_display.h"
+#include "chrome/browser/chromeos/login/ui/login_display_webui.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
@@ -54,8 +54,8 @@
     OobeBaseTest::TearDownOnMainThread();
   }
 
-  WebUILoginDisplay* GetLoginDisplay() {
-    return static_cast<WebUILoginDisplay*>(
+  LoginDisplayWebUI* GetLoginDisplay() {
+    return static_cast<LoginDisplayWebUI*>(
         ExistingUserController::current_controller()->login_display());
   }
 
diff --git a/chrome/browser/chromeos/login/saml/saml_browsertest.cc b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
index 169257b..bb1d8359 100644
--- a/chrome/browser/chromeos/login/saml/saml_browsertest.cc
+++ b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
@@ -32,7 +32,7 @@
 #include "chrome/browser/chromeos/login/test/oobe_base_test.h"
 #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host_webui.h"
-#include "chrome/browser/chromeos/login/ui/webui_login_display.h"
+#include "chrome/browser/chromeos/login/ui/login_display_webui.h"
 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
 #include "chrome/browser/chromeos/policy/affiliation_test_helper.h"
diff --git a/chrome/browser/chromeos/login/session/chrome_session_manager_browsertest.cc b/chrome/browser/chromeos/login/session/chrome_session_manager_browsertest.cc
index cc46db0..db3fa2d 100644
--- a/chrome/browser/chromeos/login/session/chrome_session_manager_browsertest.cc
+++ b/chrome/browser/chromeos/login/session/chrome_session_manager_browsertest.cc
@@ -15,8 +15,8 @@
 #include "chrome/browser/chromeos/login/login_manager_test.h"
 #include "chrome/browser/chromeos/login/startup_utils.h"
 #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h"
+#include "chrome/browser/chromeos/login/ui/login_display_webui.h"
 #include "chrome/browser/chromeos/login/ui/user_adding_screen.h"
-#include "chrome/browser/chromeos/login/ui/webui_login_display.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
 #include "chromeos/chromeos_switches.h"
@@ -104,7 +104,7 @@
       chrome::NOTIFICATION_SESSION_STARTED,
       content::NotificationService::AllSources());
 
-  WebUILoginDisplay* login_display = static_cast<WebUILoginDisplay*>(
+  LoginDisplayWebUI* login_display = static_cast<LoginDisplayWebUI*>(
       ExistingUserController::current_controller()->login_display());
   login_display->ShowSigninScreenForCreds(kTestUsers[0].email, "fake_password");
 
diff --git a/chrome/browser/chromeos/login/test/oobe_base_test.cc b/chrome/browser/chromeos/login/test/oobe_base_test.cc
index 6425433..e15b1253 100644
--- a/chrome/browser/chromeos/login/test/oobe_base_test.cc
+++ b/chrome/browser/chromeos/login/test/oobe_base_test.cc
@@ -212,11 +212,11 @@
   return LoginDisplayHost::default_host()->GetOobeUI()->web_ui();
 }
 
-WebUILoginDisplay* OobeBaseTest::GetLoginDisplay() {
+LoginDisplayWebUI* OobeBaseTest::GetLoginDisplay() {
   ExistingUserController* controller =
       ExistingUserController::current_controller();
   CHECK(controller);
-  return static_cast<WebUILoginDisplay*>(controller->login_display());
+  return static_cast<LoginDisplayWebUI*>(controller->login_display());
 }
 
 void OobeBaseTest::WaitForGaiaPageLoad() {
diff --git a/chrome/browser/chromeos/login/test/oobe_base_test.h b/chrome/browser/chromeos/login/test/oobe_base_test.h
index 0d27d2c..f4f142a 100644
--- a/chrome/browser/chromeos/login/test/oobe_base_test.h
+++ b/chrome/browser/chromeos/login/test/oobe_base_test.h
@@ -13,7 +13,7 @@
 #include "chrome/browser/chromeos/login/test/https_forwarder.h"
 #include "chrome/browser/chromeos/login/test/js_checker.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host_webui.h"
-#include "chrome/browser/chromeos/login/ui/webui_login_display.h"
+#include "chrome/browser/chromeos/login/ui/login_display_webui.h"
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "content/public/test/test_utils.h"
@@ -88,7 +88,7 @@
   content::WebUI* GetLoginUI();
 
   // Returns login display.
-  WebUILoginDisplay* GetLoginDisplay();
+  LoginDisplayWebUI* GetLoginDisplay();
 
   void WaitForGaiaPageLoad();
   void WaitForGaiaPageReload();
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_webui.cc b/chrome/browser/chromeos/login/ui/login_display_host_webui.cc
index 9158d4c..9cf43a6 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_webui.cc
+++ b/chrome/browser/chromeos/login/ui/login_display_host_webui.cc
@@ -47,7 +47,7 @@
 #include "chrome/browser/chromeos/login/startup_utils.h"
 #include "chrome/browser/chromeos/login/ui/input_events_blocker.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host_views.h"
-#include "chrome/browser/chromeos/login/ui/webui_login_display.h"
+#include "chrome/browser/chromeos/login/ui/login_display_webui.h"
 #include "chrome/browser/chromeos/login/ui/webui_login_view.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
 #include "chrome/browser/chromeos/mobile_config.h"
@@ -584,8 +584,8 @@
 
 LoginDisplay* LoginDisplayHostWebUI::CreateLoginDisplay(
     LoginDisplay::Delegate* delegate) {
-  webui_login_display_ = new WebUILoginDisplay(delegate);
-  return webui_login_display_;
+  login_display_ = new LoginDisplayWebUI(delegate);
+  return login_display_;
 }
 
 gfx::NativeWindow LoginDisplayHostWebUI::GetNativeWindow() const {
@@ -722,17 +722,17 @@
   existing_user_controller_.reset(new chromeos::ExistingUserController(this));
 
   if (!signin_screen_controller_.get()) {
-    signin_screen_controller_.reset(new SignInScreenController(
-        GetOobeUI(), webui_login_display_->delegate()));
+    signin_screen_controller_.reset(
+        new SignInScreenController(GetOobeUI(), login_display_->delegate()));
   }
 
   SetOobeProgressBarVisible(oobe_progress_bar_visible_ = false);
   SetStatusAreaVisible(true);
   existing_user_controller_->Init(
       user_manager::UserManager::Get()->GetUsersAllowedForMultiProfile());
-  CHECK(webui_login_display_);
-  GetOobeUI()->ShowSigninScreen(LoginScreenContext(), webui_login_display_,
-                                webui_login_display_);
+  CHECK(login_display_);
+  GetOobeUI()->ShowSigninScreen(LoginScreenContext(), login_display_,
+                                login_display_);
 }
 
 void LoginDisplayHostWebUI::CancelUserAdding() {
@@ -787,8 +787,8 @@
   existing_user_controller_.reset(new chromeos::ExistingUserController(this));
 
   if (!signin_screen_controller_.get()) {
-    signin_screen_controller_.reset(new SignInScreenController(
-        GetOobeUI(), webui_login_display_->delegate()));
+    signin_screen_controller_.reset(
+        new SignInScreenController(GetOobeUI(), login_display_->delegate()));
   }
 
   oobe_progress_bar_visible_ = !StartupUtils::IsDeviceRegistered();
@@ -805,9 +805,8 @@
   connector->ScheduleServiceInitialization(
       kPolicyServiceInitializationDelayMilliseconds);
 
-  CHECK(webui_login_display_);
-  GetOobeUI()->ShowSigninScreen(context, webui_login_display_,
-                                webui_login_display_);
+  CHECK(login_display_);
+  GetOobeUI()->ShowSigninScreen(context, login_display_, login_display_);
   TRACE_EVENT_ASYNC_STEP_INTO0("ui", "ShowLoginWebUI", kShowLoginWebUIid,
                                "WaitForScreenStateInitialize");
   BootTimesRecorder::Get()->RecordCurrentStats(
@@ -816,7 +815,7 @@
 
 void LoginDisplayHostWebUI::OnPreferencesChanged() {
   if (is_showing_login_)
-    webui_login_display_->OnPreferencesChanged();
+    login_display_->OnPreferencesChanged();
 }
 
 void LoginDisplayHostWebUI::PrewarmAuthentication() {
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_webui.h b/chrome/browser/chromeos/login/ui/login_display_host_webui.h
index 26c75bc..6fcc698 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_webui.h
+++ b/chrome/browser/chromeos/login/ui/login_display_host_webui.h
@@ -44,7 +44,7 @@
 
 class ArcKioskController;
 class DemoAppLauncher;
-class WebUILoginDisplay;
+class LoginDisplayWebUI;
 class WebUILoginView;
 
 // An implementation class for OOBE/login WebUI screen host.
@@ -242,7 +242,7 @@
   WebUILoginView* login_view_ = nullptr;
 
   // Login display we are using.
-  WebUILoginDisplay* webui_login_display_ = nullptr;
+  LoginDisplayWebUI* login_display_ = nullptr;
 
   // True if the login display is the current screen.
   bool is_showing_login_ = false;
diff --git a/chrome/browser/chromeos/login/ui/webui_login_display.cc b/chrome/browser/chromeos/login/ui/login_display_webui.cc
similarity index 74%
rename from chrome/browser/chromeos/login/ui/webui_login_display.cc
rename to chrome/browser/chromeos/login/ui/login_display_webui.cc
index d5bc901d..6bb39bbd 100644
--- a/chrome/browser/chromeos/login/ui/webui_login_display.cc
+++ b/chrome/browser/chromeos/login/ui/login_display_webui.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/chromeos/login/ui/webui_login_display.h"
+#include "chrome/browser/chromeos/login/ui/login_display_webui.h"
 
 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
 #include "chrome/browser/chromeos/login/lock/screen_locker.h"
@@ -28,9 +28,9 @@
 
 namespace chromeos {
 
-// WebUILoginDisplay, public: --------------------------------------------------
+// LoginDisplayWebUI, public: --------------------------------------------------
 
-WebUILoginDisplay::~WebUILoginDisplay() {
+LoginDisplayWebUI::~LoginDisplayWebUI() {
   if (webui_handler_)
     webui_handler_->ResetSigninScreenHandlerDelegate();
   ui::UserActivityDetector* activity_detector = ui::UserActivityDetector::Get();
@@ -40,15 +40,15 @@
 
 // LoginDisplay implementation: ------------------------------------------------
 
-WebUILoginDisplay::WebUILoginDisplay(LoginDisplay::Delegate* delegate)
+LoginDisplayWebUI::LoginDisplayWebUI(LoginDisplay::Delegate* delegate)
     : LoginDisplay(delegate) {}
 
-void WebUILoginDisplay::ClearAndEnablePassword() {
+void LoginDisplayWebUI::ClearAndEnablePassword() {
   if (webui_handler_)
     webui_handler_->ClearAndEnablePassword();
 }
 
-void WebUILoginDisplay::Init(const user_manager::UserList& users,
+void LoginDisplayWebUI::Init(const user_manager::UserList& users,
                              bool show_guest,
                              bool show_users,
                              bool allow_new_user) {
@@ -70,11 +70,11 @@
 
 // ---- User selection screen methods
 
-void WebUILoginDisplay::HandleGetUsers() {
+void LoginDisplayWebUI::HandleGetUsers() {
   SignInScreenController::Get()->SendUserList();
 }
 
-void WebUILoginDisplay::CheckUserStatus(const AccountId& account_id) {
+void LoginDisplayWebUI::CheckUserStatus(const AccountId& account_id) {
   SignInScreenController::Get()->CheckUserStatus(account_id);
 }
 
@@ -82,12 +82,12 @@
 
 // ---- Not yet classified methods
 
-void WebUILoginDisplay::OnPreferencesChanged() {
+void LoginDisplayWebUI::OnPreferencesChanged() {
   if (webui_handler_)
     webui_handler_->OnPreferencesChanged();
 }
 
-void WebUILoginDisplay::SetUIEnabled(bool is_enabled) {
+void LoginDisplayWebUI::SetUIEnabled(bool is_enabled) {
   // TODO(nkostylev): Cleanup this condition,
   // see http://crbug.com/157885 and http://crbug.com/158255.
   // Allow this call only before user sign in or at lock screen.
@@ -103,7 +103,7 @@
     host->GetWebUILoginView()->SetUIEnabled(is_enabled);
 }
 
-void WebUILoginDisplay::ShowError(int error_msg_id,
+void LoginDisplayWebUI::ShowError(int error_msg_id,
                                   int login_attempts,
                                   HelpAppLauncher::HelpTopic help_topic_id) {
   VLOG(1) << "Show error, error_id: " << error_msg_id
@@ -155,47 +155,47 @@
                             help_topic_id);
 }
 
-void WebUILoginDisplay::ShowErrorScreen(LoginDisplay::SigninError error_id) {
+void LoginDisplayWebUI::ShowErrorScreen(LoginDisplay::SigninError error_id) {
   VLOG(1) << "Show error screen, error_id: " << error_id;
   if (!webui_handler_)
     return;
   webui_handler_->ShowErrorScreen(error_id);
 }
 
-void WebUILoginDisplay::ShowPasswordChangedDialog(bool show_password_error,
+void LoginDisplayWebUI::ShowPasswordChangedDialog(bool show_password_error,
                                                   const std::string& email) {
   if (webui_handler_)
     webui_handler_->ShowPasswordChangedDialog(show_password_error, email);
 }
 
-void WebUILoginDisplay::ShowSigninUI(const std::string& email) {
+void LoginDisplayWebUI::ShowSigninUI(const std::string& email) {
   if (webui_handler_)
     webui_handler_->ShowSigninUI(email);
 }
 
-void WebUILoginDisplay::ShowWhitelistCheckFailedError() {
+void LoginDisplayWebUI::ShowWhitelistCheckFailedError() {
   if (webui_handler_)
     webui_handler_->ShowWhitelistCheckFailedError();
 }
 
-void WebUILoginDisplay::ShowUnrecoverableCrypthomeErrorDialog() {
+void LoginDisplayWebUI::ShowUnrecoverableCrypthomeErrorDialog() {
   if (webui_handler_)
     webui_handler_->ShowUnrecoverableCrypthomeErrorDialog();
 }
 
-// WebUILoginDisplay, NativeWindowDelegate implementation: ---------------------
-gfx::NativeWindow WebUILoginDisplay::GetNativeWindow() const {
+// LoginDisplayWebUI, NativeWindowDelegate implementation: ---------------------
+gfx::NativeWindow LoginDisplayWebUI::GetNativeWindow() const {
   return parent_window();
 }
 
-// WebUILoginDisplay, SigninScreenHandlerDelegate implementation: --------------
-void WebUILoginDisplay::CancelPasswordChangedFlow() {
+// LoginDisplayWebUI, SigninScreenHandlerDelegate implementation: --------------
+void LoginDisplayWebUI::CancelPasswordChangedFlow() {
   DCHECK(delegate_);
   if (delegate_)
     delegate_->CancelPasswordChangedFlow();
 }
 
-void WebUILoginDisplay::CancelUserAdding() {
+void LoginDisplayWebUI::CancelUserAdding() {
   if (!UserAddingScreen::Get()->IsRunning()) {
     LOG(ERROR) << "User adding screen not running.";
     return;
@@ -203,146 +203,146 @@
   UserAddingScreen::Get()->Cancel();
 }
 
-void WebUILoginDisplay::CompleteLogin(const UserContext& user_context) {
+void LoginDisplayWebUI::CompleteLogin(const UserContext& user_context) {
   DCHECK(delegate_);
   if (delegate_)
     delegate_->CompleteLogin(user_context);
 }
 
-void WebUILoginDisplay::Login(const UserContext& user_context,
+void LoginDisplayWebUI::Login(const UserContext& user_context,
                               const SigninSpecifics& specifics) {
   DCHECK(delegate_);
   if (delegate_)
     delegate_->Login(user_context, specifics);
 }
 
-void WebUILoginDisplay::MigrateUserData(const std::string& old_password) {
+void LoginDisplayWebUI::MigrateUserData(const std::string& old_password) {
   DCHECK(delegate_);
   if (delegate_)
     delegate_->MigrateUserData(old_password);
 }
 
-void WebUILoginDisplay::LoadWallpaper(const AccountId& account_id) {
+void LoginDisplayWebUI::LoadWallpaper(const AccountId& account_id) {
   WallpaperManager::Get()->ShowUserWallpaper(account_id);
 }
 
-void WebUILoginDisplay::LoadSigninWallpaper() {
+void LoginDisplayWebUI::LoadSigninWallpaper() {
   WallpaperManager::Get()->ShowSigninWallpaper();
 }
 
-void WebUILoginDisplay::OnSigninScreenReady() {
+void LoginDisplayWebUI::OnSigninScreenReady() {
   SignInScreenController::Get()->OnSigninScreenReady();
 
   if (delegate_)
     delegate_->OnSigninScreenReady();
 }
 
-void WebUILoginDisplay::OnGaiaScreenReady() {
+void LoginDisplayWebUI::OnGaiaScreenReady() {
   if (delegate_)
     delegate_->OnGaiaScreenReady();
 }
 
-void WebUILoginDisplay::RemoveUser(const AccountId& account_id) {
+void LoginDisplayWebUI::RemoveUser(const AccountId& account_id) {
   SignInScreenController::Get()->RemoveUser(account_id);
 }
 
-void WebUILoginDisplay::ResyncUserData() {
+void LoginDisplayWebUI::ResyncUserData() {
   DCHECK(delegate_);
   if (delegate_)
     delegate_->ResyncUserData();
 }
 
-void WebUILoginDisplay::ShowEnterpriseEnrollmentScreen() {
+void LoginDisplayWebUI::ShowEnterpriseEnrollmentScreen() {
   if (delegate_)
     delegate_->OnStartEnterpriseEnrollment();
 }
 
-void WebUILoginDisplay::ShowEnableDebuggingScreen() {
+void LoginDisplayWebUI::ShowEnableDebuggingScreen() {
   if (delegate_)
     delegate_->OnStartEnableDebuggingScreen();
 }
 
-void WebUILoginDisplay::ShowKioskEnableScreen() {
+void LoginDisplayWebUI::ShowKioskEnableScreen() {
   if (delegate_)
     delegate_->OnStartKioskEnableScreen();
 }
 
-void WebUILoginDisplay::ShowKioskAutolaunchScreen() {
+void LoginDisplayWebUI::ShowKioskAutolaunchScreen() {
   if (delegate_)
     delegate_->OnStartKioskAutolaunchScreen();
 }
 
-void WebUILoginDisplay::ShowUpdateRequiredScreen() {
+void LoginDisplayWebUI::ShowUpdateRequiredScreen() {
   if (delegate_)
     delegate_->ShowUpdateRequiredScreen();
 }
 
-void WebUILoginDisplay::ShowWrongHWIDScreen() {
+void LoginDisplayWebUI::ShowWrongHWIDScreen() {
   if (delegate_)
     delegate_->ShowWrongHWIDScreen();
 }
 
-void WebUILoginDisplay::SetWebUIHandler(
+void LoginDisplayWebUI::SetWebUIHandler(
     LoginDisplayWebUIHandler* webui_handler) {
   webui_handler_ = webui_handler;
   SignInScreenController::Get()->SetWebUIHandler(webui_handler_);
 }
 
-void WebUILoginDisplay::ShowSigninScreenForCreds(const std::string& username,
+void LoginDisplayWebUI::ShowSigninScreenForCreds(const std::string& username,
                                                  const std::string& password) {
   if (webui_handler_)
     webui_handler_->ShowSigninScreenForCreds(username, password);
 }
 
-bool WebUILoginDisplay::IsShowGuest() const {
+bool LoginDisplayWebUI::IsShowGuest() const {
   return show_guest_;
 }
 
-bool WebUILoginDisplay::IsShowUsers() const {
+bool LoginDisplayWebUI::IsShowUsers() const {
   return show_users_;
 }
 
-bool WebUILoginDisplay::ShowUsersHasChanged() const {
+bool LoginDisplayWebUI::ShowUsersHasChanged() const {
   return show_users_changed_;
 }
 
-bool WebUILoginDisplay::IsAllowNewUser() const {
+bool LoginDisplayWebUI::IsAllowNewUser() const {
   return allow_new_user_;
 }
 
-bool WebUILoginDisplay::AllowNewUserChanged() const {
+bool LoginDisplayWebUI::AllowNewUserChanged() const {
   return allow_new_user_changed_;
 }
 
-bool WebUILoginDisplay::IsSigninInProgress() const {
+bool LoginDisplayWebUI::IsSigninInProgress() const {
   return delegate_->IsSigninInProgress();
 }
 
-bool WebUILoginDisplay::IsUserSigninCompleted() const {
+bool LoginDisplayWebUI::IsUserSigninCompleted() const {
   return is_signin_completed();
 }
 
-void WebUILoginDisplay::SetDisplayEmail(const std::string& email) {
+void LoginDisplayWebUI::SetDisplayEmail(const std::string& email) {
   if (delegate_)
     delegate_->SetDisplayEmail(email);
 }
 
-void WebUILoginDisplay::SetDisplayAndGivenName(const std::string& display_name,
+void LoginDisplayWebUI::SetDisplayAndGivenName(const std::string& display_name,
                                                const std::string& given_name) {
   if (delegate_)
     delegate_->SetDisplayAndGivenName(display_name, given_name);
 }
 
-void WebUILoginDisplay::Signout() {
+void LoginDisplayWebUI::Signout() {
   delegate_->Signout();
 }
 
-void WebUILoginDisplay::OnUserActivity(const ui::Event* event) {
+void LoginDisplayWebUI::OnUserActivity(const ui::Event* event) {
   if (delegate_)
     delegate_->ResetAutoLoginTimer();
 }
 
-bool WebUILoginDisplay::IsUserWhitelisted(const AccountId& account_id) {
+bool LoginDisplayWebUI::IsUserWhitelisted(const AccountId& account_id) {
   DCHECK(delegate_);
   if (delegate_)
     return delegate_->IsUserWhitelisted(account_id);
diff --git a/chrome/browser/chromeos/login/ui/webui_login_display.h b/chrome/browser/chromeos/login/ui/login_display_webui.h
similarity index 91%
rename from chrome/browser/chromeos/login/ui/webui_login_display.h
rename to chrome/browser/chromeos/login/ui/login_display_webui.h
index 37039c1..969f03f 100644
--- a/chrome/browser/chromeos/login/ui/webui_login_display.h
+++ b/chrome/browser/chromeos/login/ui/login_display_webui.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_UI_WEBUI_LOGIN_DISPLAY_H_
-#define CHROME_BROWSER_CHROMEOS_LOGIN_UI_WEBUI_LOGIN_DISPLAY_H_
+#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_UI_LOGIN_DISPLAY_WEBUI_H_
+#define CHROME_BROWSER_CHROMEOS_LOGIN_UI_LOGIN_DISPLAY_WEBUI_H_
 
 #include <string>
 #include <vector>
@@ -23,13 +23,13 @@
 namespace chromeos {
 
 // WebUI-based login UI implementation.
-class WebUILoginDisplay : public LoginDisplay,
+class LoginDisplayWebUI : public LoginDisplay,
                           public NativeWindowDelegate,
                           public SigninScreenHandlerDelegate,
                           public ui::UserActivityObserver {
  public:
-  explicit WebUILoginDisplay(LoginDisplay::Delegate* delegate);
-  ~WebUILoginDisplay() override;
+  explicit LoginDisplayWebUI(LoginDisplay::Delegate* delegate);
+  ~LoginDisplayWebUI() override;
 
   // LoginDisplay implementation:
   void ClearAndEnablePassword() override;
@@ -115,9 +115,9 @@
   // Reference to the WebUI handling layer for the login screen
   LoginDisplayWebUIHandler* webui_handler_ = nullptr;
 
-  DISALLOW_COPY_AND_ASSIGN(WebUILoginDisplay);
+  DISALLOW_COPY_AND_ASSIGN(LoginDisplayWebUI);
 };
 
 }  // namespace chromeos
 
-#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_UI_WEBUI_LOGIN_DISPLAY_H_
+#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_UI_LOGIN_DISPLAY_WEBUI_H_
diff --git a/chrome/browser/chromeos/login/ui/webui_login_view.cc b/chrome/browser/chromeos/login/ui/webui_login_view.cc
index 0d46148..01626129 100644
--- a/chrome/browser/chromeos/login/ui/webui_login_view.cc
+++ b/chrome/browser/chromeos/login/ui/webui_login_view.cc
@@ -26,10 +26,10 @@
 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
 #include "chrome/browser/chromeos/lock_screen_apps/state_controller.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host_webui.h"
+#include "chrome/browser/chromeos/login/ui/login_display_webui.h"
 #include "chrome/browser/chromeos/login/ui/preloaded_web_view.h"
 #include "chrome/browser/chromeos/login/ui/preloaded_web_view_factory.h"
 #include "chrome/browser/chromeos/login/ui/web_contents_forced_title.h"
-#include "chrome/browser/chromeos/login/ui/webui_login_display.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h"
 #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
diff --git a/chrome/browser/chromeos/login/webview_login_browsertest.cc b/chrome/browser/chromeos/login/webview_login_browsertest.cc
index 4914db7..5e9a32d 100644
--- a/chrome/browser/chromeos/login/webview_login_browsertest.cc
+++ b/chrome/browser/chromeos/login/webview_login_browsertest.cc
@@ -11,7 +11,7 @@
 #include "chrome/browser/chromeos/login/signin_partition_manager.h"
 #include "chrome/browser/chromeos/login/test/oobe_base_test.h"
 #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h"
-#include "chrome/browser/chromeos/login/ui/webui_login_display.h"
+#include "chrome/browser/chromeos/login/ui/login_display_webui.h"
 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/ui/webui/signin/signin_utils.h"
diff --git a/chrome/browser/chromeos/policy/blocking_login_browsertest.cc b/chrome/browser/chromeos/policy/blocking_login_browsertest.cc
index cace55c..2ea76a44 100644
--- a/chrome/browser/chromeos/policy/blocking_login_browsertest.cc
+++ b/chrome/browser/chromeos/policy/blocking_login_browsertest.cc
@@ -15,7 +15,7 @@
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/login/existing_user_controller.h"
 #include "chrome/browser/chromeos/login/test/oobe_base_test.h"
-#include "chrome/browser/chromeos/login/ui/webui_login_display.h"
+#include "chrome/browser/chromeos/login/ui/login_display_webui.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
@@ -161,8 +161,8 @@
     ExistingUserController* controller =
         ExistingUserController::current_controller();
     ASSERT_TRUE(controller);
-    WebUILoginDisplay* login_display =
-        static_cast<WebUILoginDisplay*>(controller->login_display());
+    LoginDisplayWebUI* login_display =
+        static_cast<LoginDisplayWebUI*>(controller->login_display());
     ASSERT_TRUE(login_display);
 
     login_display->ShowSigninScreenForCreds(username, "password");
diff --git a/chrome/browser/chromeos/policy/login_policy_test_base.cc b/chrome/browser/chromeos/policy/login_policy_test_base.cc
index 0af6aba..3336142 100644
--- a/chrome/browser/chromeos/policy/login_policy_test_base.cc
+++ b/chrome/browser/chromeos/policy/login_policy_test_base.cc
@@ -6,7 +6,7 @@
 
 #include "base/values.h"
 #include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/chromeos/login/ui/webui_login_display.h"
+#include "chrome/browser/chromeos/login/ui/login_display_webui.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
 #include "chrome/browser/chromeos/policy/user_policy_test_helper.h"
 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_browsertest.cc b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_browsertest.cc
index 16757f97..13d156f5 100644
--- a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_browsertest.cc
+++ b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_browsertest.cc
@@ -10,7 +10,7 @@
 #include "base/run_loop.h"
 #include "base/values.h"
 #include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/chromeos/login/ui/webui_login_display.h"
+#include "chrome/browser/chromeos/login/ui/login_display_webui.h"
 #include "chrome/browser/chromeos/policy/login_policy_test_base.h"
 #include "chrome/browser/chromeos/policy/user_policy_test_helper.h"
 #include "chrome/browser/prefs/session_startup_pref.h"
diff --git a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
index ef8b495..396e39c 100644
--- a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
+++ b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
@@ -812,14 +812,12 @@
         // Clear https-only previews types.
         previews_state &= ~(content::NOSCRIPT_ON);
       }
-      if (previews_state != response->head.previews_state) {
-        // Update previews state in response to renderer.
-        response->head.previews_state = previews_state;
-        // Update previews state in nav data to UI.
-        ChromeNavigationData* data =
-            ChromeNavigationData::GetDataAndCreateIfNecessary(request);
-        data->set_previews_state(previews_state);
-      }
+      // Update previews state in response to renderer.
+      response->head.previews_state = previews_state;
+      // Update previews state in nav data to UI.
+      ChromeNavigationData* data =
+          ChromeNavigationData::GetDataAndCreateIfNecessary(request);
+      data->set_previews_state(previews_state);
     }
   }
 
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_impl.cc b/chrome/browser/media/router/mojo/media_router_mojo_impl.cc
index 64b78c62..97279e8 100644
--- a/chrome/browser/media/router/mojo/media_router_mojo_impl.cc
+++ b/chrome/browser/media/router/mojo/media_router_mojo_impl.cc
@@ -538,6 +538,14 @@
   }
 }
 
+bool MediaRouterMojoImpl::ProviderSinkAvailability::IsAvailableForProvider(
+    MediaRouteProviderId provider_id) const {
+  const auto& it = availabilities_.find(provider_id);
+  return it == availabilities_.end()
+             ? false
+             : it->second != SinkAvailability::UNAVAILABLE;
+}
+
 bool MediaRouterMojoImpl::ProviderSinkAvailability::IsAvailable() const {
   return overall_availability_ != SinkAvailability::UNAVAILABLE;
 }
@@ -578,9 +586,11 @@
 
   // If sink availability is UNAVAILABLE or the query isn't new, then there is
   // no need to call MRPs.
-  if (availability_.IsAvailable() && is_new_query) {
-    for (const auto& provider : media_route_providers_)
-      provider.second->StartObservingMediaSinks(source_id);
+  if (is_new_query) {
+    for (const auto& provider : media_route_providers_) {
+      if (sink_availability_.IsAvailableForProvider(provider.first))
+        provider.second->StartObservingMediaSinks(source_id);
+    }
   }
   return true;
 }
@@ -591,9 +601,8 @@
 
   const MediaSource::Id& source_id = observer->source().id();
   auto it = sinks_queries_.find(source_id);
-  if (it == sinks_queries_.end() || !it->second->HasObserver(observer)) {
+  if (it == sinks_queries_.end() || !it->second->HasObserver(observer))
     return;
-  }
 
   // If we are removing the final observer for the source, then stop
   // observing sinks for it.
@@ -603,8 +612,8 @@
   if (!it->second->HasObservers()) {
     // Only ask MRPs to stop observing media sinks if there are sinks available.
     // Otherwise, the MRPs would have discarded the queries already.
-    if (availability_.IsAvailable()) {
-      for (const auto& provider : media_route_providers_)
+    for (const auto& provider : media_route_providers_) {
+      if (sink_availability_.IsAvailableForProvider(provider.first))
         provider.second->StopObservingMediaSinks(source_id);
     }
     sinks_queries_.erase(source_id);
@@ -753,16 +762,15 @@
 void MediaRouterMojoImpl::OnSinkAvailabilityUpdated(
     MediaRouteProviderId provider_id,
     SinkAvailability availability) {
-  if (!availability_.SetAvailabilityForProvider(provider_id, availability))
+  if (!sink_availability_.SetAvailabilityForProvider(provider_id, availability))
     return;
 
-  if (availability_.IsAvailable()) {
-    // Sinks are now available. Tell MRPs to start all sink queries again.
-    for (const auto& source_and_query : sinks_queries_) {
-      for (const auto& provider : media_route_providers_)
-        provider.second->StartObservingMediaSinks(source_and_query.first);
-    }
-  } else {
+  if (availability != SinkAvailability::UNAVAILABLE) {
+    // Sinks are now available. Tell the MRP to start all sink queries again.
+    auto& provider = media_route_providers_[provider_id];
+    for (const auto& source_and_query : sinks_queries_)
+      provider->StartObservingMediaSinks(source_and_query.first);
+  } else if (!sink_availability_.IsAvailable()) {
     // Sinks are no longer available. MRPs have already removed all sink
     // queries.
     for (auto& source_and_query : sinks_queries_)
@@ -807,7 +815,7 @@
     MediaRouteProviderId provider_id) {
   const auto& provider = media_route_providers_[provider_id];
   // Sink queries.
-  if (availability_.IsAvailable()) {
+  if (sink_availability_.IsAvailableForProvider(provider_id)) {
     for (const auto& it : sinks_queries_)
       provider->StartObservingMediaSinks(it.first);
   }
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_impl.h b/chrome/browser/media/router/mojo/media_router_mojo_impl.h
index 9d0089e..f14016b5 100644
--- a/chrome/browser/media/router/mojo/media_router_mojo_impl.h
+++ b/chrome/browser/media/router/mojo/media_router_mojo_impl.h
@@ -296,6 +296,9 @@
     bool SetAvailabilityForProvider(MediaRouteProviderId provider_id,
                                     SinkAvailability availability);
 
+    // Returns true if the availability for the provider is not UNAVAILABLE.
+    bool IsAvailableForProvider(MediaRouteProviderId provider_id) const;
+
     // Returns true if there is a provider whose sink availability isn't
     // UNAVAILABLE.
     bool IsAvailable() const;
@@ -407,7 +410,7 @@
   std::string instance_id_;
 
   // The last reported sink availability from the media route providers.
-  ProviderSinkAvailability availability_;
+  ProviderSinkAvailability sink_availability_;
 
   // Bindings for Mojo pointers to |this| held by media route providers.
   mojo::BindingSet<mojom::MediaRouter> bindings_;
diff --git a/chrome/browser/media/router/mojo/wired_display_media_route_provider.cc b/chrome/browser/media/router/mojo/wired_display_media_route_provider.cc
index 9df4e9d..ac508f0e 100644
--- a/chrome/browser/media/router/mojo/wired_display_media_route_provider.cc
+++ b/chrome/browser/media/router/mojo/wired_display_media_route_provider.cc
@@ -68,6 +68,7 @@
     : binding_(this, std::move(request)),
       media_router_(std::move(media_router)) {
   display::Screen::GetScreen()->AddObserver(this);
+  ReportSinkAvailability(GetSinks());
 }
 
 WiredDisplayMediaRouteProvider::~WiredDisplayMediaRouteProvider() {
@@ -264,6 +265,7 @@
 void WiredDisplayMediaRouteProvider::NotifySinkObservers() {
   std::vector<MediaSinkInternal> sinks = GetSinks();
   device_count_metrics_.RecordDeviceCountsIfNeeded(sinks.size(), sinks.size());
+  ReportSinkAvailability(sinks);
   for (const auto& sink_query : sink_queries_)
     media_router_->OnSinksReceived(kProviderId, sink_query, sinks, {});
 }
@@ -290,4 +292,12 @@
   return displays;
 }
 
+void WiredDisplayMediaRouteProvider::ReportSinkAvailability(
+    const std::vector<MediaSinkInternal>& sinks) {
+  mojom::MediaRouter::SinkAvailability sink_availability =
+      sinks.empty() ? mojom::MediaRouter::SinkAvailability::UNAVAILABLE
+                    : mojom::MediaRouter::SinkAvailability::PER_SOURCE;
+  media_router_->OnSinkAvailabilityUpdated(kProviderId, sink_availability);
+}
+
 }  // namespace media_router
diff --git a/chrome/browser/media/router/mojo/wired_display_media_route_provider.h b/chrome/browser/media/router/mojo/wired_display_media_route_provider.h
index 0cfd0e7..f126b45 100644
--- a/chrome/browser/media/router/mojo/wired_display_media_route_provider.h
+++ b/chrome/browser/media/router/mojo/wired_display_media_route_provider.h
@@ -106,6 +106,9 @@
   // Sends the current list of sinks to each query in |sink_queries_|.
   void NotifySinkObservers();
 
+  // Notifies |media_router_| of the current sink availability.
+  void ReportSinkAvailability(const std::vector<MediaSinkInternal>& sinks);
+
   // Returns a list of available sinks. A display can be a sink if it is
   // secondary and does not mirror a primary display.
   std::vector<MediaSinkInternal> GetSinks() const;
diff --git a/chrome/browser/media/router/mojo/wired_display_media_route_provider_unittest.cc b/chrome/browser/media/router/mojo/wired_display_media_route_provider_unittest.cc
index eb831353..d4f6cc5f 100644
--- a/chrome/browser/media/router/mojo/wired_display_media_route_provider_unittest.cc
+++ b/chrome/browser/media/router/mojo/wired_display_media_route_provider_unittest.cc
@@ -157,6 +157,39 @@
   base::RunLoop().RunUntilIdle();
 }
 
+TEST_F(WiredDisplayMediaRouteProviderTest, NotifyOnDisplayChange) {
+  const std::string sink_id1 = GetSinkId(sink_display1_);
+  provider_pointer_->StartObservingMediaSinks(kPresentationSource);
+  base::RunLoop().RunUntilIdle();
+
+  // Add an external display. MediaRouter should be notified of the sink and the
+  // sink availability change.
+  provider_->set_all_displays({primary_display_, sink_display1_});
+  EXPECT_CALL(router_, OnSinkAvailabilityUpdated(
+                           MediaRouteProviderId::WIRED_DISPLAY,
+                           mojom::MediaRouter::SinkAvailability::PER_SOURCE));
+  EXPECT_CALL(router_,
+              OnSinksReceived(MediaRouteProviderId::WIRED_DISPLAY, _, _, _))
+      .WillOnce(WithArg<2>(
+          Invoke([&sink_id1](const std::vector<MediaSinkInternal>& sinks) {
+            EXPECT_EQ(sinks.size(), 1u);
+            EXPECT_EQ(sinks[0].sink().id(), sink_id1);
+          })));
+  provider_->OnDisplayAdded(sink_display1_);
+  base::RunLoop().RunUntilIdle();
+
+  // Remove the external display. MediaRouter should be notified of the lack of
+  // sinks.
+  provider_->set_all_displays({primary_display_});
+  EXPECT_CALL(router_, OnSinkAvailabilityUpdated(
+                           MediaRouteProviderId::WIRED_DISPLAY,
+                           mojom::MediaRouter::SinkAvailability::UNAVAILABLE));
+  EXPECT_CALL(router_, OnSinksReceived(MediaRouteProviderId::WIRED_DISPLAY, _,
+                                       IsEmpty(), _));
+  provider_->OnDisplayRemoved(sink_display1_);
+  base::RunLoop().RunUntilIdle();
+}
+
 TEST_F(WiredDisplayMediaRouteProviderTest, NoSinksForNonPresentationSource) {
   EXPECT_CALL(router_,
               OnSinksReceived(kProviderId, kNonPresentationSource, _, _))
diff --git a/chrome/browser/previews/previews_browsertest.cc b/chrome/browser/previews/previews_browsertest.cc
index c385b414..dc77bb48 100644
--- a/chrome/browser/previews/previews_browsertest.cc
+++ b/chrome/browser/previews/previews_browsertest.cc
@@ -4,6 +4,7 @@
 
 #include "base/command_line.h"
 #include "base/run_loop.h"
+#include "base/test/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
@@ -97,11 +98,15 @@
 // a script resource. Verifies that the noscript tag is not evaluated and the
 // script resource is loaded.
 IN_PROC_BROWSER_TEST_F(PreviewsBrowserTest, NoScriptPreviewsDisabled) {
+  base::HistogramTester histogram_tester;
   ui_test_utils::NavigateToURL(browser(), https_url());
 
   // Verify loaded js resource but not css triggered by noscript tag.
   EXPECT_TRUE(noscript_js_requested());
   EXPECT_FALSE(noscript_css_requested());
+
+  // Verify info bar not presented via histogram check.
+  histogram_tester.ExpectTotalCount("Previews.InfoBarAction.NoScript", 0);
 }
 
 // This test class enables NoScriptPreviews but without OptimizationHints.
@@ -138,11 +143,15 @@
 // script resource is not loaded.
 IN_PROC_BROWSER_TEST_F(PreviewsNoScriptBrowserTest,
                        MAYBE_NoScriptPreviewsEnabled) {
+  base::HistogramTester histogram_tester;
   ui_test_utils::NavigateToURL(browser(), https_url());
 
   // Verify loaded noscript tag triggered css resource but not js one.
   EXPECT_TRUE(noscript_css_requested());
   EXPECT_FALSE(noscript_js_requested());
+
+  // Verify info bar presented via histogram check.
+  histogram_tester.ExpectUniqueSample("Previews.InfoBarAction.NoScript", 0, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(PreviewsNoScriptBrowserTest,
@@ -156,11 +165,15 @@
 
 IN_PROC_BROWSER_TEST_F(PreviewsNoScriptBrowserTest,
                        MAYBE_NoScriptPreviewsEnabledHttpRedirectToHttps) {
+  base::HistogramTester histogram_tester;
   ui_test_utils::NavigateToURL(browser(), redirect_url());
 
   // Verify loaded noscript tag triggered css resource but not js one.
   EXPECT_TRUE(noscript_css_requested());
   EXPECT_FALSE(noscript_js_requested());
+
+  // Verify info bar presented via histogram check.
+  histogram_tester.ExpectUniqueSample("Previews.InfoBarAction.NoScript", 0, 1);
 }
 
 // This test class enables NoScriptPreviews with OptimizationHints.
diff --git a/chrome/browser/resources/pdf/manifest.json b/chrome/browser/resources/pdf/manifest.json
index 33a1e96f..3b45a058c 100644
--- a/chrome/browser/resources/pdf/manifest.json
+++ b/chrome/browser/resources/pdf/manifest.json
@@ -9,6 +9,7 @@
   "incognito": "split",
   "permissions": [
     "<all_urls>",
+    "metricsPrivate",
     "resourcesPrivate"
   ],
   "mime_types": [
diff --git a/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc
index c532c956..3b1bf6e 100644
--- a/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/eula_screen_handler.cc
@@ -15,8 +15,8 @@
 #include "chrome/browser/chromeos/login/oobe_screen.h"
 #include "chrome/browser/chromeos/login/screens/core_oobe_view.h"
 #include "chrome/browser/chromeos/login/screens/eula_screen.h"
+#include "chrome/browser/chromeos/login/ui/login_display_webui.h"
 #include "chrome/browser/chromeos/login/ui/login_web_dialog.h"
-#include "chrome/browser/chromeos/login/ui/webui_login_display.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/grit/chromium_strings.h"
diff --git a/chrome/browser/ui/webui/chromeos/login/network_dropdown_handler.cc b/chrome/browser/ui/webui/chromeos/login/network_dropdown_handler.cc
index 70f3982..648236b9 100644
--- a/chrome/browser/ui/webui/chromeos/login/network_dropdown_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/network_dropdown_handler.cc
@@ -5,7 +5,7 @@
 #include "chrome/browser/ui/webui/chromeos/login/network_dropdown_handler.h"
 
 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
-#include "chrome/browser/chromeos/login/ui/webui_login_display.h"
+#include "chrome/browser/chromeos/login/ui/login_display_webui.h"
 #include "chrome/browser/chromeos/options/network_config_view.h"
 #include "chrome/browser/ui/webui/chromeos/login/network_dropdown.h"
 #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
index 1a6188f..20fd9fb6 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -53,8 +53,8 @@
 #include "chrome/browser/chromeos/login/startup_utils.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host_webui.h"
+#include "chrome/browser/chromeos/login/ui/login_display_webui.h"
 #include "chrome/browser/chromeos/login/ui/login_feedback.h"
-#include "chrome/browser/chromeos/login/ui/webui_login_display.h"
 #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h"
 #include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
diff --git a/chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.cc
index 5fb1f0b..c940bc4 100644
--- a/chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.cc
@@ -15,7 +15,7 @@
 #include "chrome/browser/chromeos/login/existing_user_controller.h"
 #include "chrome/browser/chromeos/login/oobe_screen.h"
 #include "chrome/browser/chromeos/login/screens/user_image_screen.h"
-#include "chrome/browser/chromeos/login/ui/webui_login_display.h"
+#include "chrome/browser/chromeos/login/ui/login_display_webui.h"
 #include "chrome/browser/chromeos/login/users/default_user_image/default_user_images.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/url_constants.h"
diff --git a/components/crash/core/common/crash_key_unittest.cc b/components/crash/core/common/crash_key_unittest.cc
index 00313f0..33a4caa 100644
--- a/components/crash/core/common/crash_key_unittest.cc
+++ b/components/crash/core/common/crash_key_unittest.cc
@@ -69,6 +69,9 @@
 }
 #endif
 
+// In certain build configurations, StackTrace will produce an
+// empty result, which will cause the test to fail.
+#if !defined(OFFICIAL_BUILD) && !defined(NO_UNWIND_TABLES)
 TEST_F(CrashKeyStringTest, SetStackTrace) {
   static CrashKeyString<1024> key("test-trace");
 
@@ -78,6 +81,7 @@
 
   EXPECT_TRUE(key.is_set());
 }
+#endif
 
 TEST_F(CrashKeyStringTest, BaseSupport) {
   static base::debug::CrashKeyString* crash_key =
diff --git a/components/sync/engine_impl/model_type_registry.cc b/components/sync/engine_impl/model_type_registry.cc
index eaa74e0..44e9c551 100644
--- a/components/sync/engine_impl/model_type_registry.cc
+++ b/components/sync/engine_impl/model_type_registry.cc
@@ -296,7 +296,7 @@
 void ModelTypeRegistry::OnPassphraseAccepted() {
   for (const auto& worker : model_type_workers_) {
     if (encrypted_types_.Has(worker->GetModelType())) {
-      worker->EncryptionAcceptedApplyUpdates();
+      worker->EncryptionAcceptedMaybeApplyUpdates();
     }
   }
 }
diff --git a/components/sync/engine_impl/model_type_worker.cc b/components/sync/engine_impl/model_type_worker.cc
index a9fc4d509..a38c0de2 100644
--- a/components/sync/engine_impl/model_type_worker.cc
+++ b/components/sync/engine_impl/model_type_worker.cc
@@ -218,11 +218,16 @@
   ApplyPendingUpdates();
 }
 
-void ModelTypeWorker::EncryptionAcceptedApplyUpdates() {
+void ModelTypeWorker::EncryptionAcceptedMaybeApplyUpdates() {
   DCHECK(cryptographer_);
   DCHECK(cryptographer_->is_ready());
-  // Reuse ApplyUpdates(...) to get its DCHECKs as well.
-  ApplyUpdates(nullptr);
+
+  // Only push the encryption to the processor if we're already connected.
+  // Otherwise this information can wait for the initial sync's first apply.
+  if (model_type_state_.initial_sync_done()) {
+    // Reuse ApplyUpdates(...) to get its DCHECKs as well.
+    ApplyUpdates(nullptr);
+  }
 }
 
 void ModelTypeWorker::ApplyPendingUpdates() {
diff --git a/components/sync/engine_impl/model_type_worker.h b/components/sync/engine_impl/model_type_worker.h
index a72b341..098fccb 100644
--- a/components/sync/engine_impl/model_type_worker.h
+++ b/components/sync/engine_impl/model_type_worker.h
@@ -95,7 +95,7 @@
 
   // An alternative way to drive sending data to the processor, that should be
   // called when a new encryption mechanism is ready.
-  void EncryptionAcceptedApplyUpdates();
+  void EncryptionAcceptedMaybeApplyUpdates();
 
   // Callback for when our contribution gets a response.
   void OnCommitResponse(CommitResponseDataList* response_list);
diff --git a/components/sync/engine_impl/model_type_worker_unittest.cc b/components/sync/engine_impl/model_type_worker_unittest.cc
index ea68ead..5233e89 100644
--- a/components/sync/engine_impl/model_type_worker_unittest.cc
+++ b/components/sync/engine_impl/model_type_worker_unittest.cc
@@ -285,6 +285,7 @@
     if (worker()) {
       worker()->UpdateCryptographer(
           std::make_unique<Cryptographer>(*cryptographer_));
+      worker()->EncryptionAcceptedMaybeApplyUpdates();
     }
   }
 
@@ -667,7 +668,7 @@
 
   ASSERT_EQ(1U, processor()->GetNumUpdateResponses());
   UpdateResponseDataList updates_list = processor()->GetNthUpdateResponse(0);
-  ASSERT_EQ(1U, updates_list.size());
+  EXPECT_EQ(1U, updates_list.size());
 
   ASSERT_TRUE(processor()->HasUpdateResponse(kHash1));
   UpdateResponseData update = processor()->GetUpdateResponse(kHash1);
@@ -694,7 +695,7 @@
 
   // A partial update response doesn't pass anything to the processor.
   TriggerPartialUpdateFromServer(10, kTag1, kValue1);
-  ASSERT_EQ(0U, processor()->GetNumUpdateResponses());
+  EXPECT_EQ(0U, processor()->GetNumUpdateResponses());
 
   // Trigger the completion of the update.
   TriggerUpdateFromServer(10, kTag2, kValue2);
@@ -721,7 +722,7 @@
   server()->SetProgressMarkerToken("token2");
   DeliverRawUpdates(SyncEntityList());
   ASSERT_EQ(1U, processor()->GetNumUpdateResponses());
-  ASSERT_EQ(
+  EXPECT_EQ(
       server()->GetProgress().SerializeAsString(),
       processor()->GetNthUpdateState(0).progress_marker().SerializeAsString());
 }
@@ -730,16 +731,11 @@
 TEST_F(ModelTypeWorkerTest, EncryptedCommit) {
   NormalInitialize();
 
-  ASSERT_EQ(0U, processor()->GetNumUpdateResponses());
+  EXPECT_EQ(0U, processor()->GetNumUpdateResponses());
 
-  // Tell the worker about the new encryption key but no ApplyUpdates yet.
+  // Init the Cryptographer, it'll cause the EKN to be pushed.
   AddPendingKey();
   DecryptPendingKey();
-  EXPECT_EQ(0, nudge_handler()->GetNumCommitNudges());
-  ASSERT_EQ(0U, processor()->GetNumUpdateResponses());
-
-  // Now the information is allowed to reach the processor.
-  ApplyUpdates();
   ASSERT_EQ(1U, processor()->GetNumUpdateResponses());
   EXPECT_EQ(GetLocalCryptographerKeyName(),
             processor()->GetNthUpdateState(0).encryption_key_name());
@@ -770,19 +766,18 @@
 
   // Update encryption key name, should be blocked.
   AddPendingKey();
-  ASSERT_EQ(0U, processor()->GetNumUpdateResponses());
+  EXPECT_EQ(0U, processor()->GetNumUpdateResponses());
 
   // Update progress marker, should be blocked.
   server()->SetProgressMarkerToken("token2");
   DeliverRawUpdates(SyncEntityList());
-  ASSERT_EQ(0U, processor()->GetNumUpdateResponses());
+  EXPECT_EQ(0U, processor()->GetNumUpdateResponses());
 
   // Update local cryptographer, verify everything is pushed to processor.
   DecryptPendingKey();
-  ApplyUpdates();
   ASSERT_EQ(1U, processor()->GetNumUpdateResponses());
   UpdateResponseDataList updates_list = processor()->GetNthUpdateResponse(0);
-  ASSERT_EQ(
+  EXPECT_EQ(
       server()->GetProgress().SerializeAsString(),
       processor()->GetNthUpdateState(0).progress_marker().SerializeAsString());
 }
@@ -877,14 +872,10 @@
   NormalInitialize();
 
   // Shouldn't be informed of the EKN, since there's a pending key.
-  ASSERT_EQ(0U, processor()->GetNumUpdateResponses());
+  EXPECT_EQ(0U, processor()->GetNumUpdateResponses());
 
-  // Although the cryptographer is ready, it should wait until being told to
-  // update the processor.
+  // Init the cryptographer, it'll push the EKN.
   DecryptPendingKey();
-  ASSERT_EQ(0U, processor()->GetNumUpdateResponses());
-
-  ApplyUpdates();
   ASSERT_EQ(1U, processor()->GetNumUpdateResponses());
   EXPECT_EQ(GetLocalCryptographerKeyName(),
             processor()->GetNthUpdateState(0).encryption_key_name());
@@ -900,7 +891,25 @@
   FirstInitialize();
 
   // Shouldn't be informed of the EKN, since normal activation will drive this.
-  ASSERT_EQ(0U, processor()->GetNumUpdateResponses());
+  EXPECT_EQ(0U, processor()->GetNumUpdateResponses());
+
+  // Now perform first sync and make sure the EKN makes it.
+  TriggerTypeRootUpdateFromServer();
+  ASSERT_EQ(1U, processor()->GetNumUpdateResponses());
+  EXPECT_EQ(GetLocalCryptographerKeyName(),
+            processor()->GetNthUpdateState(0).encryption_key_name());
+}
+
+TEST_F(ModelTypeWorkerTest, CryptographerDuringInitialization) {
+  // Initialize with initial sync done to false.
+  FirstInitialize();
+
+  // Set up the Cryptographer logic after initialization but before first sync.
+  AddPendingKey();
+  DecryptPendingKey();
+
+  // Shouldn't be informed of the EKN, since normal activation will drive this.
+  EXPECT_EQ(0U, processor()->GetNumUpdateResponses());
 
   // Now perform first sync and make sure the EKN makes it.
   TriggerTypeRootUpdateFromServer();
@@ -924,15 +933,11 @@
 
   // At this point, the cryptographer does not have access to the key, so the
   // updates will be undecryptable. This will block all updates.
-  ASSERT_EQ(0U, processor()->GetNumUpdateResponses());
+  EXPECT_EQ(0U, processor()->GetNumUpdateResponses());
 
-  // The update can be delivered once the cryptographer is ready, but it'll
-  // still wait for the apply call.
+  // The update should know that the cryptographer is ready.
   DecryptPendingKey();
-  ASSERT_EQ(0U, processor()->GetNumUpdateResponses());
-
-  // ApplyUpdates() will cause everything to finally be delivered.
-  ApplyUpdates();
+  EXPECT_EQ(1U, processor()->GetNumUpdateResponses());
   ASSERT_TRUE(processor()->HasUpdateResponse(kHash1));
   UpdateResponseData update = processor()->GetUpdateResponse(kHash1);
   EXPECT_EQ(kTag1, update.entity->specifics.preference().name());
@@ -961,7 +966,7 @@
 
   // Update will be undecryptable at first.
   EXPECT_EQ(0U, processor()->GetNumUpdateResponses());
-  ASSERT_FALSE(processor()->HasUpdateResponse(kHash1));
+  EXPECT_FALSE(processor()->HasUpdateResponse(kHash1));
 
   // Update the cryptographer so it can decrypt that update.
   AddPendingKey();
diff --git a/components/ukm/content/source_url_recorder.cc b/components/ukm/content/source_url_recorder.cc
index 573ead4..22eda75 100644
--- a/components/ukm/content/source_url_recorder.cc
+++ b/components/ukm/content/source_url_recorder.cc
@@ -41,6 +41,8 @@
   void DidFinishNavigation(
       content::NavigationHandle* navigation_handle) override;
 
+  ukm::SourceId GetLastCommittedSourceId();
+
  private:
   explicit SourceUrlRecorderWebContentsObserver(
       content::WebContents* web_contents);
@@ -53,12 +55,15 @@
   // Map from navigation ID to the initial URL for that navigation.
   base::flat_map<int64_t, GURL> pending_navigations_;
 
+  int64_t last_committed_source_id_;
+
   DISALLOW_COPY_AND_ASSIGN(SourceUrlRecorderWebContentsObserver);
 };
 
 SourceUrlRecorderWebContentsObserver::SourceUrlRecorderWebContentsObserver(
     content::WebContents* web_contents)
-    : content::WebContentsObserver(web_contents) {}
+    : content::WebContentsObserver(web_contents),
+      last_committed_source_id_(ukm::kInvalidSourceId) {}
 
 void SourceUrlRecorderWebContentsObserver::DidStartNavigation(
     content::NavigationHandle* navigation_handle) {
@@ -86,6 +91,14 @@
   if (it == pending_navigations_.end())
     return;
 
+  DCHECK(navigation_handle->IsInMainFrame());
+  DCHECK(!navigation_handle->IsSameDocument());
+
+  if (navigation_handle->HasCommitted()) {
+    last_committed_source_id_ = ukm::ConvertToSourceId(
+        navigation_handle->GetNavigationId(), ukm::SourceIdType::NAVIGATION_ID);
+  }
+
   GURL initial_url = std::move(it->second);
   pending_navigations_.erase(it);
 
@@ -96,6 +109,10 @@
   MaybeRecordUrl(navigation_handle, initial_url);
 }
 
+ukm::SourceId SourceUrlRecorderWebContentsObserver::GetLastCommittedSourceId() {
+  return last_committed_source_id_;
+}
+
 void SourceUrlRecorderWebContentsObserver::MaybeRecordUrl(
     content::NavigationHandle* navigation_handle,
     const GURL& initial_url) {
@@ -136,4 +153,10 @@
   SourceUrlRecorderWebContentsObserver::CreateForWebContents(web_contents);
 }
 
+SourceId GetSourceIdForWebContentsDocument(content::WebContents* web_contents) {
+  SourceUrlRecorderWebContentsObserver* obs =
+      SourceUrlRecorderWebContentsObserver::FromWebContents(web_contents);
+  return obs ? obs->GetLastCommittedSourceId() : kInvalidSourceId;
+}
+
 }  // namespace ukm
diff --git a/components/ukm/content/source_url_recorder.h b/components/ukm/content/source_url_recorder.h
index d124bc4..eff5124 100644
--- a/components/ukm/content/source_url_recorder.h
+++ b/components/ukm/content/source_url_recorder.h
@@ -5,6 +5,8 @@
 #ifndef COMPONENTS_UKM_CONTENT_SOURCE_URL_RECORDER_H_
 #define COMPONENTS_UKM_CONTENT_SOURCE_URL_RECORDER_H_
 
+#include "services/metrics/public/cpp/ukm_source_id.h"
+
 namespace content {
 class WebContents;
 }  // namespace content
@@ -15,6 +17,10 @@
 void InitializeSourceUrlRecorderForWebContents(
     content::WebContents* web_contents);
 
+// Get a UKM SourceId for the currently committed document of web contents.
+// Returns kInvalidSourceId if no commit has been observed.
+SourceId GetSourceIdForWebContentsDocument(content::WebContents* web_contents);
+
 }  // namespace ukm
 
 #endif  // COMPONENTS_UKM_CONTENT_SOURCE_URL_RECORDER_H_
diff --git a/components/ukm/content/source_url_recorder_browsertest.cc b/components/ukm/content/source_url_recorder_browsertest.cc
index 692f9a4..25d5d41 100644
--- a/components/ukm/content/source_url_recorder_browsertest.cc
+++ b/components/ukm/content/source_url_recorder_browsertest.cc
@@ -40,6 +40,12 @@
     return test_ukm_recorder_->GetSourceForSourceId(source_id);
   }
 
+  GURL GetAssociatedURLForWebContentsDocument() {
+    const ukm::UkmSource* src = test_ukm_recorder_->GetSourceForSourceId(
+        ukm::GetSourceIdForWebContentsDocument(shell()->web_contents()));
+    return src ? src->url() : GURL();
+  }
+
  private:
   base::test::ScopedFeatureList scoped_feature_list_;
   std::unique_ptr<ukm::TestAutoSetUkmRecorder> test_ukm_recorder_;
@@ -79,6 +85,8 @@
   EXPECT_NE(nullptr, source);
   EXPECT_EQ(url, source->url());
   EXPECT_TRUE(source->initial_url().is_empty());
+
+  EXPECT_EQ(url, GetAssociatedURLForWebContentsDocument());
 }
 
 IN_PROC_BROWSER_TEST_F(SourceUrlRecorderWebContentsObserverBrowserTest,
@@ -88,6 +96,7 @@
   content::NavigateToURL(shell(), url);
   EXPECT_TRUE(observer.has_committed());
   EXPECT_EQ(nullptr, GetSourceForNavigationId(observer.navigation_id()));
+  EXPECT_EQ(GURL(), GetAssociatedURLForWebContentsDocument());
 }
 
 IN_PROC_BROWSER_TEST_F(SourceUrlRecorderWebContentsObserverBrowserTest,
@@ -111,6 +120,8 @@
   EXPECT_EQ(main_url, source->url());
   EXPECT_EQ(nullptr,
             GetSourceForNavigationId(subframe_observer.navigation_id()));
+
+  EXPECT_EQ(main_url, GetAssociatedURLForWebContentsDocument());
 }
 
 IN_PROC_BROWSER_TEST_F(SourceUrlRecorderWebContentsObserverDownloadBrowserTest,
@@ -121,4 +132,5 @@
   EXPECT_FALSE(observer.has_committed());
   EXPECT_TRUE(observer.is_download());
   EXPECT_EQ(nullptr, GetSourceForNavigationId(observer.navigation_id()));
+  EXPECT_EQ(GURL(), GetAssociatedURLForWebContentsDocument());
 }
diff --git a/components/ukm/content/source_url_recorder_test.cc b/components/ukm/content/source_url_recorder_test.cc
index dc5d392..dc8ed15b 100644
--- a/components/ukm/content/source_url_recorder_test.cc
+++ b/components/ukm/content/source_url_recorder_test.cc
@@ -22,6 +22,12 @@
     ukm::InitializeSourceUrlRecorderForWebContents(web_contents());
   }
 
+  GURL GetAssociatedURLForWebContentsDocument() {
+    const ukm::UkmSource* src = test_ukm_recorder_.GetSourceForSourceId(
+        ukm::GetSourceIdForWebContentsDocument(web_contents()));
+    return src ? src->url() : GURL();
+  }
+
  protected:
   ukm::TestAutoSetUkmRecorder test_ukm_recorder_;
 };
@@ -52,12 +58,16 @@
     EXPECT_EQ(final_url, kv.second->url());
     EXPECT_EQ(initial_url, kv.second->initial_url());
   }
+
+  EXPECT_EQ(final_url, GetAssociatedURLForWebContentsDocument());
 }
 
 TEST_F(SourceUrlRecorderWebContentsObserverTest, IgnoreUnsupportedScheme) {
   NavigationSimulator::NavigateAndCommitFromBrowser(web_contents(),
                                                     GURL("about:blank"));
   EXPECT_EQ(0ul, test_ukm_recorder_.sources_count());
+
+  EXPECT_EQ(GURL(), GetAssociatedURLForWebContentsDocument());
 }
 
 TEST_F(SourceUrlRecorderWebContentsObserverTest, IgnoreUrlInSubframe) {
@@ -75,6 +85,8 @@
     EXPECT_EQ(main_frame_url, kv.second->url());
     EXPECT_TRUE(kv.second->initial_url().is_empty());
   }
+
+  EXPECT_EQ(main_frame_url, GetAssociatedURLForWebContentsDocument());
 }
 
 TEST_F(SourceUrlRecorderWebContentsObserverTest, IgnoreSameDocumentNavigation) {
@@ -92,4 +104,6 @@
     EXPECT_EQ(url, kv.second->url());
     EXPECT_TRUE(kv.second->initial_url().is_empty());
   }
+
+  EXPECT_EQ(url, GetAssociatedURLForWebContentsDocument());
 }
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index 87adf48..2ed9c26 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -1632,12 +1632,8 @@
 #endif
   ui::Clipboard::SetAllowedThreads(allowed_clipboard_threads);
 
-  // When running the GPU thread in-process, avoid optimistically starting it
-  // since creating the GPU thread races against creation of the one-and-only
-  // ChildProcess instance which is created by the renderer thread.
   if (GpuDataManagerImpl::GetInstance()->GpuAccessAllowed(nullptr) &&
-      !established_gpu_channel && always_uses_gpu && !UsingInProcessGpu() &&
-      browser_is_viz_host) {
+      !established_gpu_channel && always_uses_gpu && browser_is_viz_host) {
     TRACE_EVENT_INSTANT0("gpu", "Post task to launch GPU process",
                          TRACE_EVENT_SCOPE_THREAD);
     BrowserThread::PostTask(
diff --git a/content/browser/renderer_host/media/media_stream_manager_unittest.cc b/content/browser/renderer_host/media/media_stream_manager_unittest.cc
index 6947037..db870f3 100644
--- a/content/browser/renderer_host/media/media_stream_manager_unittest.cc
+++ b/content/browser/renderer_host/media/media_stream_manager_unittest.cc
@@ -18,7 +18,6 @@
 #include "content/browser/browser_thread_impl.h"
 #include "content/browser/renderer_host/media/media_stream_manager.h"
 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
-#include "content/browser/renderer_host/media/mock_video_capture_provider.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "media/audio/audio_device_description.h"
@@ -44,7 +43,6 @@
 #endif
 
 using testing::_;
-using testing::Invoke;
 
 namespace content {
 
@@ -140,19 +138,9 @@
     audio_manager_ = std::make_unique<MockAudioManager>();
     audio_system_ =
         std::make_unique<media::AudioSystemImpl>(audio_manager_.get());
-    auto video_capture_provider = std::make_unique<MockVideoCaptureProvider>();
-    video_capture_provider_ = video_capture_provider.get();
     media_stream_manager_ = std::make_unique<MediaStreamManager>(
-        audio_system_.get(), audio_manager_->GetTaskRunner(),
-        std::move(video_capture_provider));
+        audio_system_.get(), audio_manager_->GetTaskRunner());
     base::RunLoop().RunUntilIdle();
-
-    ON_CALL(*video_capture_provider_, DoGetDeviceInfosAsync(_))
-        .WillByDefault(Invoke(
-            [](VideoCaptureProvider::GetDeviceInfosCallback& result_callback) {
-              std::vector<media::VideoCaptureDeviceInfo> stub_results;
-              base::ResetAndReturn(&result_callback).Run(stub_results);
-            }));
   }
 
   ~MediaStreamManagerTest() override { audio_manager_->Shutdown(); }
@@ -188,7 +176,6 @@
   content::TestBrowserThreadBundle thread_bundle_;
   std::unique_ptr<MockAudioManager> audio_manager_;
   std::unique_ptr<media::AudioSystem> audio_system_;
-  MockVideoCaptureProvider* video_capture_provider_;
   base::RunLoop run_loop_;
 
  private:
diff --git a/content/browser/renderer_host/media/service_video_capture_provider.cc b/content/browser/renderer_host/media/service_video_capture_provider.cc
index 6b73cd1..b837db09 100644
--- a/content/browser/renderer_host/media/service_video_capture_provider.cc
+++ b/content/browser/renderer_host/media/service_video_capture_provider.cc
@@ -20,28 +20,20 @@
  public:
   ServiceConnectorImpl() {
     DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
-    // In unit test environments, there may not be any connector.
-    auto* connection = content::ServiceManagerConnection::GetForProcess();
-    if (!connection)
-      return;
-    auto* connector = connection->GetConnector();
-    if (!connector)
-      return;
-    connector_ = connector->Clone();
+    connector_ = content::ServiceManagerConnection::GetForProcess()
+                     ->GetConnector()
+                     ->Clone();
+    DETACH_FROM_SEQUENCE(sequence_checker_);
   }
 
   void BindFactoryProvider(
       video_capture::mojom::DeviceFactoryProviderPtr* provider) override {
-    if (!connector_) {
-      CHECK(false) << "Attempted to connect to the video capture service from "
-                      "a process that does not provide a "
-                      "ServiceManagerConnection";
-    }
     connector_->BindInterface(video_capture::mojom::kServiceName, provider);
   }
 
  private:
   std::unique_ptr<service_manager::Connector> connector_;
+  SEQUENCE_CHECKER(sequence_checker_);
 };
 
 }  // anonymous namespace
diff --git a/content/renderer/media/user_media_processor.cc b/content/renderer/media/user_media_processor.cc
index 7faa066..d5c65a2 100644
--- a/content/renderer/media/user_media_processor.cc
+++ b/content/renderer/media/user_media_processor.cc
@@ -456,7 +456,14 @@
       GetUserMediaRequestFailed(result, failed_constraint_name);
       return;
     }
-    SelectVideoContentSettings();
+    base::PostTaskAndReplyWithResult(
+        worker_task_runner_.get(), FROM_HERE,
+        base::Bind(&SelectSettingsVideoContentCapture,
+                   current_request_info_->web_request().VideoConstraints(),
+                   video_controls.stream_source),
+        base::Bind(&UserMediaProcessor::FinalizeSelectVideoContentSettings,
+                   weak_factory_.GetWeakPtr(),
+                   current_request_info_->web_request()));
   }
 }
 
@@ -506,12 +513,13 @@
   GenerateStreamForCurrentRequestInfo();
 }
 
-void UserMediaProcessor::SelectVideoContentSettings() {
+void UserMediaProcessor::FinalizeSelectVideoContentSettings(
+    const blink::WebUserMediaRequest& web_request,
+    const VideoCaptureSettings& settings) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(current_request_info_);
-  VideoCaptureSettings settings = SelectSettingsVideoContentCapture(
-      current_request_info_->web_request().VideoConstraints(),
-      current_request_info_->stream_controls()->video.stream_source);
+  if (!IsCurrentRequestInfo(web_request))
+    return;
+
   if (!settings.HasValue()) {
     blink::WebString failed_constraint_name =
         blink::WebString::FromASCII(settings.failed_constraint_name());
diff --git a/content/renderer/media/user_media_processor.h b/content/renderer/media/user_media_processor.h
index 743b9333..99f844b 100644
--- a/content/renderer/media/user_media_processor.h
+++ b/content/renderer/media/user_media_processor.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 #include <string>
-#include <utility>
 #include <vector>
 
 #include "base/callback_forward.h"
@@ -256,7 +255,9 @@
   void FinalizeSelectVideoDeviceSettings(
       const blink::WebUserMediaRequest& web_request,
       const VideoCaptureSettings& settings);
-  void SelectVideoContentSettings();
+  void FinalizeSelectVideoContentSettings(
+      const blink::WebUserMediaRequest& web_request,
+      const VideoCaptureSettings& settings);
 
   void GenerateStreamForCurrentRequestInfo();
 
diff --git a/extensions/common/api/_permission_features.json b/extensions/common/api/_permission_features.json
index 19f665e..dd78145b 100644
--- a/extensions/common/api/_permission_features.json
+++ b/extensions/common/api/_permission_features.json
@@ -397,7 +397,8 @@
       "2B6C6A4A5940017146F3E58B7F90116206E84685",  // http://crbug.com/642141
       "B6C2EFAB3EC3BF6EF03701408B6B09A67B2D0069",  // http://crbug.com/642141
       "96FF2FFA5C9173C76D47184B3E86D267B37781DE",  // http://crbug.com/642141
-      "0136FCB13DB29FD5CD442F56E59E53B61F1DF96F"   // http://crbug.com/642141
+      "0136FCB13DB29FD5CD442F56E59E53B61F1DF96F",  // http://crbug.com/642141
+      "CBCC42ABED43A4B58FE3810E62AFFA010EB0349F"   // PDF Viewer
     ]
   },
   "nativeMessaging": {
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd
index e3416f2..1bda950 100644
--- a/ios/chrome/app/strings/ios_strings.grd
+++ b/ios/chrome/app/strings/ios_strings.grd
@@ -708,8 +708,8 @@
       <message name="IDS_IOS_NEW_TAB_INCOGNITO" desc="Title for the Incognito panel of the new tab page.">
         Incognito
       </message>
-      <message name="IDS_IOS_NEW_TAB_IPH_PROMOTION_TEXT" desc="Text for the New Tab Tip in-product help promotion, explaining that new tabs can be opened. [iOS only]" meaning="The user has never created a new tab, and a bubble is displayed pointing to the tab switcher to inform users how to create tabs.">
-        Create multiple tabs for all your tasks
+      <message name="IDS_IOS_NEW_TAB_IPH_PROMOTION_TEXT" desc="Text for the New Tab Tip in-product help promotion, explaining that new tabs can be added and switched between. [iOS only]" meaning="The user has never created a new tab, and a bubble is displayed pointing to the tab switcher to inform users how to create tabs and switch between them.">
+        Add tabs and switch between pages
       </message>
       <message name="IDS_IOS_NEW_TAB_LEARN_MORE_ABOUT_SUGGESTED_CONTENT" desc="Text in the footer of the New Tab Page. Part of the text is a link to a help center page where the user can learn more about suggested content.">
         <ph name="BEGIN_LINK">BEGIN_LINK</ph>Learn more<ph name="END_LINK">END_LINK</ph> about suggested content
diff --git a/media/test/pipeline_integration_test.cc b/media/test/pipeline_integration_test.cc
index 508dd96..ec89f78 100644
--- a/media/test/pipeline_integration_test.cc
+++ b/media/test/pipeline_integration_test.cc
@@ -833,10 +833,8 @@
   Stop();
 }
 
-// The test is flaky, see https://crbug.com/788387.
-TEST_F(PipelineIntegrationTest,
-       DISABLED_ReinitRenderersWhileVideoTrackIsDisabled) {
-  ASSERT_EQ(PIPELINE_OK, Start("bear-320x240.webm", kHashed));
+TEST_F(PipelineIntegrationTest, ReinitRenderersWhileVideoTrackIsDisabled) {
+  ASSERT_EQ(PIPELINE_OK, Start("bear-320x240.webm", kHashed | kNoClockless));
   Play();
 
   // These get triggered every time playback is resumed.
diff --git a/net/BUILD.gn b/net/BUILD.gn
index 17641e4..8800fdb 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -82,8 +82,6 @@
   ":net_internal_config",
   "//build/config:precompiled_headers",
 
-  # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
-  "//build/config/compiler:no_size_t_to_int_warning",
   "//build/config/compiler:wexit_time_destructors",
 ]
 
@@ -2309,7 +2307,6 @@
     "server/web_socket_encoder.h",
   ]
   configs += [
-    "//build/config/compiler:no_size_t_to_int_warning",
     "//build/config/compiler:wexit_time_destructors",
   ]
   deps = [
@@ -2327,9 +2324,6 @@
       "tools/dump_cache/dump_files.h",
     ]
 
-    # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
-    configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
-
     deps = [
       ":net",
       ":test_support",
@@ -2667,9 +2661,6 @@
 
   configs += [
     "//build/config:precompiled_headers",
-
-    # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
-    "//build/config/compiler:no_size_t_to_int_warning",
   ]
 
   public_deps = [
@@ -2776,7 +2767,6 @@
     defines = [ "NET_IMPLEMENTATION" ]
 
     configs += [
-      "//build/config/compiler:no_size_t_to_int_warning",
       "//build/config/compiler:wexit_time_destructors",
       "//v8:external_startup_data",
     ]
@@ -2841,8 +2831,6 @@
       "tools/cert_verify_tool/verify_using_path_builder.h",
     ]
 
-    # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
-    configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
     deps = [
       ":net",
       ":test_support",
@@ -2862,8 +2850,6 @@
       "tools/crash_cache/crash_cache.cc",
     ]
 
-    # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
-    configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
     deps = [
       ":net",
       ":test_support",
@@ -2879,8 +2865,6 @@
       "tools/crl_set_dump/crl_set_dump.cc",
     ]
 
-    # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
-    configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
     deps = [
       ":net",
       "//base",
@@ -2895,8 +2879,6 @@
       "tools/dns_fuzz_stub/dns_fuzz_stub.cc",
     ]
 
-    # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
-    configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
     deps = [
       ":net",
       "//base",
@@ -2926,8 +2908,6 @@
       "tools/get_server_time/get_server_time.cc",
     ]
 
-    # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
-    configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
     deps = [
       ":net",
       "//base",
@@ -2944,8 +2924,6 @@
       "spdy/core/fuzzing/hpack_example_generator.cc",
     ]
 
-    # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
-    configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
     deps = [
       ":net",
       "//base",
@@ -2991,8 +2969,6 @@
       "tools/stress_cache/stress_cache.cc",
     ]
 
-    # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
-    configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
     deps = [
       ":net",
       ":test_support",
@@ -3007,8 +2983,6 @@
       "tools/tld_cleanup/tld_cleanup.cc",
     ]
 
-    # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
-    configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
     deps = [
       "//base",
       "//base:i18n",
@@ -5334,9 +5308,6 @@
 
   configs += [
     "//build/config:precompiled_headers",
-
-    # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
-    "//build/config/compiler:no_size_t_to_int_warning",
   ]
   defines = []
 
@@ -5767,8 +5738,6 @@
       "url_request/url_request_quic_perftest.cc",
     ]
 
-    # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
-    configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
     deps = [
       ":extras",
       ":net",
diff --git a/services/ui/ws/remote_event_dispatcher.cc b/services/ui/ws/remote_event_dispatcher.cc
index c220ecd..a652c8731 100644
--- a/services/ui/ws/remote_event_dispatcher.cc
+++ b/services/ui/ws/remote_event_dispatcher.cc
@@ -33,6 +33,14 @@
     return;
   }
 
+  if (event->IsLocatedEvent()) {
+    LocatedEvent* located_event = event->AsLocatedEvent();
+    if (located_event->root_location_f() != located_event->location_f()) {
+      DVLOG(1) << "RemoteEventDispatcher::DispatchEvent locations must match";
+      cb.Run(false);
+      return;
+    }
+  }
   ignore_result(static_cast<PlatformDisplayDelegate*>(display)
                     ->GetEventSink()
                     ->OnEventFromSource(event.get()));
diff --git a/services/video_capture/public/cpp/constants.cc b/services/video_capture/public/cpp/constants.cc
index 42390d7c..37a25ed 100644
--- a/services/video_capture/public/cpp/constants.cc
+++ b/services/video_capture/public/cpp/constants.cc
@@ -4,18 +4,9 @@
 
 #include "services/video_capture/public/cpp/constants.h"
 
-#include "build/build_config.h"
-
 namespace video_capture {
 
-const base::Feature kMojoVideoCapture {
-  "MojoVideoCapture",
-#if (defined(OS_LINUX) && !defined(OS_CHROMEOS)) || defined(OS_MACOSX) || \
-    defined(OS_WIN)
-      base::FEATURE_ENABLED_BY_DEFAULT
-#else
-      base::FEATURE_DISABLED_BY_DEFAULT
-#endif
-};
+const base::Feature kMojoVideoCapture{"MojoVideoCapture",
+                                      base::FEATURE_DISABLED_BY_DEFAULT};
 
 }  // namespace video_capture
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json
index 06b0b8e..00bdd27 100644
--- a/testing/buildbot/chromium.android.json
+++ b/testing/buildbot/chromium.android.json
@@ -673,6 +673,7 @@
   },
   "Cast Android (dbg)": {
     "additional_compile_targets": [
+      "cast_junit_test_lists",
       "cast_shell_apk"
     ]
   },
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 44adc59..0934855f 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -3869,10 +3869,7 @@
   },
   "Fuchsia": {
     "additional_compile_targets": [
-      "content_browsertests",
-      "content_shell",
-      "gl_unittests",
-      "headless_shell"
+      "gn_all"
     ],
     "gtest_tests": [
       {
@@ -4069,12 +4066,7 @@
   },
   "Fuchsia (dbg)": {
     "additional_compile_targets": [
-      "content_browsertests",
-      "content_shell",
-      "content_unittests",
-      "gl_unittests",
-      "media_unittests",
-      "net_unittests"
+      "gn_all"
     ],
     "gtest_tests": [
       {
@@ -4242,13 +4234,7 @@
   },
   "Fuchsia ARM64": {
     "additional_compile_targets": [
-      "content_browsertests",
-      "content_shell",
-      "content_unittests",
-      "gl_unittests",
-      "headless_shell",
-      "media_unittests",
-      "net_unittests"
+      "gn_all"
     ],
     "gtest_tests": [
       {
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json
index b4ffa78..8966e43 100644
--- a/testing/buildbot/chromium.linux.json
+++ b/testing/buildbot/chromium.linux.json
@@ -1,3067 +1,6 @@
 {
   "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {},
   "AAAAA2 See generate_buildbot_json.py to make changes": {},
-  "Android Arm64 Builder (dbg)": {
-    "additional_compile_targets": [
-      "all"
-    ]
-  },
-  "Android Builder": {
-    "additional_compile_targets": [
-      "cronet_test_instrumentation_apk",
-      "monochrome_static_initializers"
-    ]
-  },
-  "Android Clang Builder (dbg)": {
-    "additional_compile_targets": [
-      "all"
-    ]
-  },
-  "Android Tests": {
-    "gtest_tests": [
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "base_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "base_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "blink_heap_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 180,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "blink_heap_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "boringssl_crypto_tests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "boringssl_crypto_tests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "boringssl_ssl_tests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "boringssl_ssl_tests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "breakpad_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "breakpad_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "capture_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "capture_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "cc_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "cc_unittests"
-      },
-      {
-        "args": [
-          "--gs-results-bucket=chromium-result-details"
-        ],
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "chrome_public_test_apk"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 1500,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ],
-          "shards": 12
-        },
-        "test": "chrome_public_test_apk"
-      },
-      {
-        "args": [
-          "--gs-results-bucket=chromium-result-details"
-        ],
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "chrome_sync_shell_test_apk"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 960,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "chrome_sync_shell_test_apk"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "components_browsertests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "components_browsertests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "components_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 900,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ],
-          "shards": 2
-        },
-        "test": "components_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "content_browsertests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 1500,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ],
-          "shards": 8
-        },
-        "test": "content_browsertests"
-      },
-      {
-        "args": [
-          "--gs-results-bucket=chromium-result-details"
-        ],
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "content_shell_test_apk"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 960,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ],
-          "shards": 3
-        },
-        "test": "content_shell_test_apk"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "content_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 960,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "content_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "device_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "device_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "events_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "events_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "gl_tests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "gl_tests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "gl_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 60,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "gl_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "gpu_ipc_service_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "gpu_ipc_service_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "gpu_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "gpu_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "ipc_tests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "ipc_tests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "libjingle_xmpp_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "libjingle_xmpp_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "media_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "media_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "mojo_common_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 60,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "mojo_common_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "mojo_public_bindings_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 60,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "mojo_public_bindings_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "mojo_public_system_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 60,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "mojo_public_system_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "mojo_system_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 180,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "mojo_system_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "mojo_test_apk"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 300,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "mojo_test_apk"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "net_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 900,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ],
-          "shards": 3
-        },
-        "test": "net_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "sandbox_linux_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "sandbox_linux_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "services_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 120,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "services_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "sql_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "sql_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "storage_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 180,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "storage_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "ui_android_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "ui_android_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "ui_base_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "ui_base_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "ui_touch_selection_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "ui_touch_selection_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "unit_tests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 900,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "unit_tests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "viz_unittests"
-      }
-    ],
-    "junit_tests": [
-      {
-        "test": "base_junit_tests"
-      },
-      {
-        "test": "chrome_junit_tests"
-      },
-      {
-        "test": "components_background_task_scheduler_junit_tests"
-      },
-      {
-        "test": "components_gcm_driver_junit_tests"
-      },
-      {
-        "test": "components_invalidation_impl_junit_tests"
-      },
-      {
-        "test": "components_policy_junit_tests"
-      },
-      {
-        "test": "components_variations_junit_tests"
-      },
-      {
-        "test": "components_web_restrictions_junit_tests"
-      },
-      {
-        "test": "content_junit_tests"
-      },
-      {
-        "test": "device_junit_tests"
-      },
-      {
-        "test": "junit_unit_tests"
-      },
-      {
-        "test": "net_junit_tests"
-      },
-      {
-        "test": "service_junit_tests"
-      },
-      {
-        "test": "ui_junit_tests"
-      },
-      {
-        "test": "webapk_client_junit_tests"
-      },
-      {
-        "test": "webapk_shell_apk_junit_tests"
-      }
-    ]
-  },
-  "Android Tests (dbg)": {
-    "gtest_tests": [
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "base_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "base_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "blink_heap_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 180,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "blink_heap_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "boringssl_crypto_tests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "boringssl_crypto_tests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "boringssl_ssl_tests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "boringssl_ssl_tests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "breakpad_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "breakpad_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "capture_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "capture_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "cc_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "cc_unittests"
-      },
-      {
-        "args": [
-          "--gs-results-bucket=chromium-result-details"
-        ],
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "chrome_public_test_apk"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 1500,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ],
-          "shards": 20
-        },
-        "test": "chrome_public_test_apk"
-      },
-      {
-        "args": [
-          "--gs-results-bucket=chromium-result-details"
-        ],
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "chrome_sync_shell_test_apk"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 960,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ],
-          "shards": 2
-        },
-        "test": "chrome_sync_shell_test_apk"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "components_browsertests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "components_browsertests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "components_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 900,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ],
-          "shards": 2
-        },
-        "test": "components_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "content_browsertests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 1500,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ],
-          "shards": 8
-        },
-        "test": "content_browsertests"
-      },
-      {
-        "args": [
-          "--gs-results-bucket=chromium-result-details"
-        ],
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "content_shell_test_apk"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 960,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ],
-          "shards": 3
-        },
-        "test": "content_shell_test_apk"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "content_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 960,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "content_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "device_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "device_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "events_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "events_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "gl_tests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "gl_tests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "gl_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 60,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "gl_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "gpu_ipc_service_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "gpu_ipc_service_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "gpu_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "gpu_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "ipc_tests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "ipc_tests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "libjingle_xmpp_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "libjingle_xmpp_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "media_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "media_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "mojo_common_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 60,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "mojo_common_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "mojo_public_bindings_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 60,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "mojo_public_bindings_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "mojo_public_system_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 60,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "mojo_public_system_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "mojo_system_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 180,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "mojo_system_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "mojo_test_apk"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 300,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "mojo_test_apk"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "net_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 900,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ],
-          "shards": 3
-        },
-        "test": "net_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "sandbox_linux_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "sandbox_linux_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "services_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 120,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "services_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "sql_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "sql_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "storage_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 180,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "storage_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "ui_android_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "ui_android_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "ui_base_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "ui_base_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "ui_touch_selection_unittests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "ui_touch_selection_unittests"
-      },
-      {
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "unit_tests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "hard_timeout": 900,
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "unit_tests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "device_os": "KTU84P",
-              "device_type": "hammerhead"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ]
-        },
-        "test": "viz_unittests"
-      }
-    ],
-    "junit_tests": [
-      {
-        "test": "base_junit_tests"
-      },
-      {
-        "test": "chrome_junit_tests"
-      },
-      {
-        "test": "components_gcm_driver_junit_tests"
-      },
-      {
-        "test": "components_invalidation_impl_junit_tests"
-      },
-      {
-        "test": "components_policy_junit_tests"
-      },
-      {
-        "test": "components_variations_junit_tests"
-      },
-      {
-        "test": "components_web_restrictions_junit_tests"
-      },
-      {
-        "test": "content_junit_tests"
-      },
-      {
-        "test": "device_junit_tests"
-      },
-      {
-        "test": "junit_unit_tests"
-      },
-      {
-        "test": "net_junit_tests"
-      },
-      {
-        "test": "service_junit_tests"
-      },
-      {
-        "test": "ui_junit_tests"
-      },
-      {
-        "test": "webapk_client_junit_tests"
-      },
-      {
-        "test": "webapk_shell_apk_junit_tests"
-      }
-    ]
-  },
-  "Cast Android (dbg)": {
-    "additional_compile_targets": [
-      "cast_junit_test_lists",
-      "cast_shell_apk",
-      "cast_test_lists"
-    ]
-  },
   "Cast Audio Linux": {
     "additional_compile_targets": [
       "cast_shell",
@@ -3440,23 +379,7 @@
   },
   "Fuchsia ARM64": {
     "additional_compile_targets": [
-      "base_unittests",
-      "content_unittests",
-      "crypto_unittests",
-      "gl_unittests",
-      "headless_shell",
-      "ipc_tests",
-      "media_unittests",
-      "mojo_common_unittests",
-      "mojo_js_unittests",
-      "mojo_public_bindings_unittests",
-      "mojo_public_system_unittests",
-      "mojo_system_unittests",
-      "net_unittests",
-      "service_manager_unittests",
-      "skia_unittests",
-      "sql_unittests",
-      "ui_base_unittests"
+      "gn_all"
     ]
   },
   "Fuchsia ARM64 Cast Audio": {
@@ -3467,21 +390,7 @@
   },
   "Fuchsia x64": {
     "additional_compile_targets": [
-      "base_unittests",
-      "content_browsertests",
-      "content_shell",
-      "gl_unittests",
-      "headless_shell",
-      "ipc_tests",
-      "media_unittests",
-      "mojo_common_unittests",
-      "mojo_js_unittests",
-      "mojo_public_bindings_unittests",
-      "mojo_public_system_unittests",
-      "mojo_system_unittests",
-      "net_unittests",
-      "service_manager_unittests",
-      "ui_base_unittests"
+      "gn_all"
     ],
     "gtest_tests": [
       {
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl
index 96b0603..ee3de66 100644
--- a/testing/buildbot/gn_isolate_map.pyl
+++ b/testing/buildbot/gn_isolate_map.pyl
@@ -387,10 +387,6 @@
     "label": "//content/public/android:content_junit_tests",
     "type": "junit_test",
   },
-  "content_shell": {
-    "label": "//content/shell:content_shell",
-    "type": "raw",
-  },
   "content_shell_crash_test": {
     "label": "//content/shell:content_shell_crash_test",
     "type": "script",
@@ -531,6 +527,10 @@
     "type": "windowed_test_launcher",
     "executable": "gl_unittests",
   },
+  "gn_all": {
+    "label": "//:gn_all",
+    "type": "additional_compile_target",
+  },
   "gn_unittests": {
     "label": "//tools/gn:gn_unittests",
     "type": "console_test_launcher",
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index cd75efa8..0ce8bf5 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -23,9 +23,6 @@
       'KitKat Phone Tester (rel)',
       'KitKat Tablet Tester',
       'Nougat Phone Tester',
-      # chromium.linux
-      'Android Tests',
-      'Android Tests (dbg)',
     ],
     'modifications': {
       'Lollipop Tablet Tester': {
@@ -131,16 +128,6 @@
       'Win7 Tests (dbg)(1)',
     ],
     'modifications': {
-      'Android Tests': {
-        'swarming': {
-          'hard_timeout': 180,
-        },
-      },
-      'Android Tests (dbg)': {
-        'swarming': {
-          'hard_timeout': 180,
-        },
-      },
       'KitKat Phone Tester (dbg)': {
         'swarming': {
           'hard_timeout': 180,
@@ -205,9 +192,6 @@
   'cacheinvalidation_unittests': {
     'remove_from': [
       # Unclear why these largely aren't run on Android.
-      # chromium.linux:
-      'Android Tests',
-      'Android Tests (dbg)',
       # chromium.android:
       'KitKat Phone Tester (dbg)',
       'KitKat Phone Tester (rel)',
@@ -263,9 +247,6 @@
   'cast_unittests': {
     'remove_from': [
       # Unclear why these largely aren't run on Android.
-      # chromium.linux:
-      'Android Tests',
-      'Android Tests (dbg)',
       # TODO(kbr): why are the cast unit tests not run on the Cast bots?!
       'Cast Audio Linux',
       'Cast Linux',
@@ -308,16 +289,6 @@
       'Marshmallow Phone Tester (rel)',
     ],
     'modifications': {
-      'Android Tests': {
-        'swarming': {
-          'shards': 12,
-        },
-      },
-      'Android Tests (dbg)': {
-        'swarming': {
-          'shards': 20,
-        },
-      },
       'KitKat Phone Tester (dbg)': {
         'swarming': {
           'shards': 20,
@@ -363,9 +334,6 @@
       'KitKat Tablet Tester',
       'Lollipop Tablet Tester',
       'Marshmallow Tablet Tester',
-      # chromium.linux
-      'Android Tests',
-      'Android Tests (dbg)',
     ],
     'modifications': {
       'Lollipop Phone Tester': {
@@ -397,11 +365,6 @@
   },
   'chrome_sync_shell_test_apk': {
     'modifications': {
-      'Android Tests (dbg)': {
-        'swarming': {
-          'shards': 2,
-        },
-      },
       'KitKat Phone Tester (dbg)': {
         'swarming': {
           'shards': 2,
@@ -435,9 +398,6 @@
       'Marshmallow Phone Tester (rel)',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
-      # On chromium.linux, unclear why these aren't run on "Android Tests
-      # (dbg)".
-      'Android Tests (dbg)',
     ],
   },
   'components_browsertests': {
@@ -638,8 +598,6 @@
       # TODO(kbr): these tests aren't run on Android except on one bot
       # on chromium.android.fyi, which might just be an accident.
       # Consider moving it to non_android_chromium_gtests.
-      'Android Tests',
-      'Android Tests (dbg)',
       'KitKat Phone Tester (dbg)',
       'KitKat Phone Tester (rel)',
       'KitKat Tablet Tester',
@@ -707,9 +665,6 @@
       'Marshmallow Phone Tester (rel)',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
-      # On chromium.linux, unclear why these aren't run on Android.
-      'Android Tests',
-      'Android Tests (dbg)',
       # chromium.win
       'Win7 Tests (dbg)(1)',
     ],
@@ -753,22 +708,12 @@
       'Linux Tests (dbg)(1)(32)',
     ],
   },
-  'gcm_unit_tests': {
-    'remove_from': [
-      # On chromium.linux, unclear why these aren't run on Android.
-      'Android Tests',
-      'Android Tests (dbg)',
-    ],
-  },
   'gfx_unittests': {
     'remove_from': [
       # On chromium.android, unclear why these aren't run on all bots.
       'KitKat Phone Tester (dbg)',
       'KitKat Phone Tester (rel)',
       'Nougat Phone Tester',
-      # On chromium.linux, unclear why these aren't run on Android.
-      'Android Tests',
-      'Android Tests (dbg)',
       # chromium.win
       'Win7 Tests (dbg)(1)',
     ],
@@ -807,9 +752,7 @@
       'Marshmallow Phone Tester (rel)',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
-      # On chromium.linux, unclear why these aren't run on Android or Cast.
-      'Android Tests',
-      'Android Tests (dbg)',
+      # On chromium.linux, unclear why these aren't run on Cast.
       'Cast Audio Linux',
       'Cast Linux',
       'Linux Tests (dbg)(1)(32)',
@@ -870,9 +813,7 @@
       'Marshmallow Phone Tester (rel)',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
-      # On chromium.linux, unclear why these aren't run on Android and Cast.
-      'Android Tests',
-      'Android Tests (dbg)',
+      # On chromium.linux, unclear why these aren't run on Cast.
       'Cast Audio Linux',
       'Cast Linux',
       # chromium.win
@@ -1008,9 +949,6 @@
       'Marshmallow Phone Tester (rel)',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
-      # On chromium.linux, unclear why these aren't run on Android.
-      'Android Tests',
-      'Android Tests (dbg)',
     ],
   },
   'keyboard_unittests': {
@@ -1032,8 +970,6 @@
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
       # On chromium.linux, unclear why these aren't run.
-      'Android Tests',
-      'Android Tests (dbg)',
       'Linux Tests',
       'Linux Tests (dbg)(1)',
       'Linux Tests (dbg)(1)(32)',
@@ -1065,9 +1001,6 @@
       'KitKat Phone Tester (rel)',
       'KitKat Tablet Tester',
       'Nougat Phone Tester',
-      # On chromium.linux, unclear why these aren't run on Android.
-      'Android Tests',
-      'Android Tests (dbg)',
     ],
     'modifications': {
       'Lollipop Tablet Tester': {
@@ -1148,9 +1081,6 @@
       'Marshmallow Phone Tester (rel)',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
-      # On chromium.linux, unclear why these aren't run on Android.
-      'Android Tests',
-      'Android Tests (dbg)',
     ],
   },
   'mojo_common_unittests': {
@@ -1324,9 +1254,7 @@
       'Marshmallow Phone Tester (rel)',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
-      # On chromium.linux, unclear why these aren't run on Android.
-      'Android Tests',
-      'Android Tests (dbg)',
+      # On chromium.linux, unclear why these aren't run on 32-bit.
       'Linux Tests (dbg)(1)(32)',
     ],
   },
@@ -1341,9 +1269,7 @@
       'Marshmallow Phone Tester (rel)',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
-      # On chromium.linux, unclear why these aren't run on Android.
-      'Android Tests',
-      'Android Tests (dbg)',
+      # On chromium.linux, unclear why these aren't run on 32-bit.
       'Linux Tests (dbg)(1)(32)',
     ],
     'modifications': {
@@ -1366,9 +1292,6 @@
       'Marshmallow Phone Tester (rel)',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
-      # chromium.linux
-      'Android Tests',
-      'Android Tests (dbg)',
     ],
     'modifications': {
       'Marshmallow 64 bit Tester': {
@@ -1390,9 +1313,7 @@
       'Marshmallow Phone Tester (rel)',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
-      # On chromium.linux, unclear why these aren't run on Android.
-      'Android Tests',
-      'Android Tests (dbg)',
+      # On chromium.linux, unclear why these aren't run on 32-bit.
       'Linux Tests (dbg)(1)(32)',
     ],
   },
@@ -1407,9 +1328,6 @@
       'Marshmallow Phone Tester (rel)',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
-      # On chromium.linux, unclear why these aren't run on Android.
-      'Android Tests',
-      'Android Tests (dbg)',
     ],
     'modifications': {
       'Marshmallow 64 bit Tester': {
@@ -1461,9 +1379,7 @@
       'Marshmallow Phone Tester (rel)',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
-      # On chromium.linux, unclear why these aren't run on Android and Cast.
-      'Android Tests',
-      'Android Tests (dbg)',
+      # On chromium.linux, unclear why these aren't run on Cast.
       'Cast Audio Linux',
       'Cast Linux',
       'Linux Tests (dbg)(1)(32)',
@@ -1548,9 +1464,7 @@
       'Marshmallow Phone Tester (rel)',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
-      # On chromium.linux, unclear why these aren't run on Android or Cast.
-      'Android Tests',
-      'Android Tests (dbg)',
+      # On chromium.linux, unclear why these aren't run on Cast.
       'Cast Audio Linux',
       'Cast Linux',
     ],
@@ -1622,17 +1536,6 @@
           'hard_timeout': 300,
         },
       },
-      # chromium.linux
-      'Android Tests': {
-        'swarming': {
-          'hard_timeout': 180,
-        },
-      },
-      'Android Tests (dbg)': {
-        'swarming': {
-          'hard_timeout': 180,
-        },
-      },
     },
   },
   'sync_integration_tests': {
@@ -1855,9 +1758,6 @@
       'Marshmallow Phone Tester (rel)',
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
-      # On chromium.linux, unclear why these aren't run on Android.
-      'Android Tests',
-      'Android Tests (dbg)',
     ],
   },
   'views_unittests': {
@@ -1882,12 +1782,6 @@
     'key_removals': {
       # TODO(kbr): on Android, it looks like the absence of the
       # "merge" key is largely an accident.
-      'Android Tests': [
-        'merge',
-      ],
-      'Android Tests (dbg)': [
-        'merge',
-      ],
       'KitKat Phone Tester (dbg)': [
         'merge',
       ],
@@ -1927,9 +1821,6 @@
       'KitKat Phone Tester (dbg)',
       'KitKat Phone Tester (rel)',
       'Nougat Phone Tester',
-      # chromium.linux
-      'Android Tests',
-      'Android Tests (dbg)',
       # chromium.win
       'Win 7 Tests x64 (1)',
       'Win10 Tests x64',
@@ -2070,8 +1961,6 @@
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
       # On chromium.linux, unclear why these only run on "Linux Tests".
-      'Android Tests',
-      'Android Tests (dbg)',
       'Cast Audio Linux',
       'Cast Linux',
       'Linux Tests (dbg)(1)',
@@ -2093,9 +1982,6 @@
       'KitKat Phone Tester (rel)',
       'KitKat Tablet Tester',
       'Nougat Phone Tester',
-      # chromium.linux
-      'Android Tests',
-      'Android Tests (dbg)',
     ],
     'modifications': {
       'Lollipop Phone Tester': {
@@ -2142,8 +2028,6 @@
       'Marshmallow Tablet Tester',
       'Nougat Phone Tester',
       # On chromium.linux, unclear why these only run on "Linux Tests".
-      'Android Tests',
-      'Android Tests (dbg)',
       'Cast Audio Linux',
       'Cast Linux',
       'Linux Tests (dbg)(1)',
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index 4575428..4ddfbd93 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -50,6 +50,7 @@
       },
       'Cast Android (dbg)': {
         'additional_compile_targets': [
+          'cast_junit_test_lists',
           'cast_shell_apk',
         ],
       },
@@ -290,48 +291,9 @@
   {
     'name': 'chromium.linux',
     'machines': {
-      'Android Arm64 Builder (dbg)': {
-        'additional_compile_targets': [
-          'all',
-        ],
-      },
-      'Android Builder': {
-        'additional_compile_targets': [
-          'cronet_test_instrumentation_apk',
-          'monochrome_static_initializers',
-        ],
-      },
-      'Android Clang Builder (dbg)': {
-        'additional_compile_targets': [
-          'all',
-        ],
-      },
-      'Cast Android (dbg)': {
-        'additional_compile_targets': [
-          'cast_junit_test_lists',
-          'cast_shell_apk',
-          'cast_test_lists',
-        ],
-      },
       'Fuchsia ARM64': {
         'additional_compile_targets': [
-          'base_unittests',
-          'content_unittests',
-          'crypto_unittests',
-          'gl_unittests',
-          'headless_shell',
-          'ipc_tests',
-          'media_unittests',
-          'mojo_common_unittests',
-          'mojo_js_unittests',
-          'mojo_public_bindings_unittests',
-          'mojo_public_system_unittests',
-          'mojo_system_unittests',
-          'net_unittests',
-          'service_manager_unittests',
-          'skia_unittests',
-          'sql_unittests',
-          'ui_base_unittests',
+          'gn_all',
         ],
       },
       'Fuchsia ARM64 Cast Audio': {
@@ -365,36 +327,6 @@
           'sync_integration_tests'
         ]
       },
-      'Android Tests': {
-        'test_suites': {
-          'gtest_tests': 'chromium_android_gtests',
-          'junit_tests': 'chromium_junit_tests',
-        },
-        'swarming': {
-          'dimension_sets': [
-            {
-              'device_os': 'KTU84P',
-              'device_type': 'hammerhead',
-            },
-          ],
-        },
-        'os_type': 'android',
-      },
-      'Android Tests (dbg)': {
-        'test_suites': {
-          'gtest_tests': 'chromium_android_gtests',
-          'junit_tests': 'chromium_junit_tests',
-        },
-        'swarming': {
-          'dimension_sets': [
-            {
-              'device_os': 'KTU84P',
-              'device_type': 'hammerhead',
-            },
-          ],
-        },
-        'os_type': 'android',
-      },
       'Cast Audio Linux': {
         'additional_compile_targets': [
           'cast_shell',
@@ -415,21 +347,7 @@
       },
       'Fuchsia x64': {
         'additional_compile_targets': [
-          'base_unittests',
-          'content_browsertests',
-          'content_shell',
-          'gl_unittests',
-          'headless_shell',
-          'ipc_tests',
-          'media_unittests',
-          'mojo_common_unittests',
-          'mojo_js_unittests',
-          'mojo_public_bindings_unittests',
-          'mojo_public_system_unittests',
-          'mojo_system_unittests',
-          'net_unittests',
-          'service_manager_unittests',
-          'ui_base_unittests',
+          'gn_all',
         ],
         'swarming': {
           'dimension_sets': [
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index bd6155a..9671cbf5 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -3636,7 +3636,7 @@
 crbug.com/789567 virtual/rootlayerscrolls/scrollbars/custom-scrollbar-adjust-on-inactive-pseudo.html [ Failure Pass ]
 crbug.com/789567 virtual/prefer_compositing_to_lcd_text/scrollbars/custom-scrollbar-inactive-pseudo.html [ Failure Pass ]
 crbug.com/789478 virtual/prefer_compositing_to_lcd_text/scrollbars/custom-scrollbar-adjust-on-inactive-pseudo.html [ Pass Failure ]
-crbug.com/789533 virtual/gpu/fast/canvas/OffscreenCanvas-2d-imageSmoothing.html [ Pass Failure ]
+crbug.com/789533 virtual/gpu/fast/canvas/OffscreenCanvas-2d-imageSmoothing.html [ Pass Failure Timeout ]
 # Sheriff failures 2017-11-30
 crbug.com/789921 [ Win7 ] media/video-controls-overflow-menu-last-button-visible.html [ Pass Failure ]
 crbug.com/789111 virtual/pwa-full-code-cache/http/tests/devtools/service-workers/service-worker-v8-cache.js [ Pass Failure Timeout ]
diff --git a/third_party/WebKit/LayoutTests/editing/selection/selection-linebreaks-rtl-writing-modes.html b/third_party/WebKit/LayoutTests/editing/selection/selection-linebreaks-rtl-writing-modes.html
new file mode 100644
index 0000000..199bb15
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/editing/selection/selection-linebreaks-rtl-writing-modes.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+
+<style>
+  iframe {
+    margin: 10px;
+    padding: 10px;
+    border: solid;
+    width: 200px;
+    height: 200px;
+    float: left;
+  }
+</style>
+
+<p>This test checks that selection of linebreaks works as expected with the different directions and writing modes.</p>
+<p>The test passes if you can visually see the linebreaks selection in the different examples.</p>
+
+<iframe srcdoc="
+  <h3>Default</h3>
+  <div id='target' contenteditable>foo<br><br><br><br>bar</div>
+  <script>
+    window.getSelection().setBaseAndExtent(target.firstChild, 2, target.lastChild, 2);
+  </script>
+"></iframe>
+
+<iframe srcdoc="
+  <h3>RTL</h3>
+  <div id='target' style='direction: rtl;' contenteditable>foo<br><br><br><br>bar</div>
+  <script>
+    window.getSelection().setBaseAndExtent(target.firstChild, 2, target.lastChild, 2);
+  </script>
+"></iframe>
+
+<iframe srcdoc="
+  <h3>vertical-lr</h3>
+  <div id='target' style='writing-mode: vertical-lr;' contenteditable>foo<br><br><br><br>bar</div>
+  <script>
+    window.getSelection().setBaseAndExtent(target.firstChild, 2, target.lastChild, 2);
+  </script>
+"></iframe>
+
+<iframe srcdoc="
+  <h3>vertical-lr &amp; RTL</h3>
+  <div id='target' style='writing-mode: vertical-lr; direction: rtl;' contenteditable>foo<br><br><br><br>bar</div>
+  <script>
+    window.getSelection().setBaseAndExtent(target.firstChild, 2, target.lastChild, 2);
+  </script>
+"></iframe>
+
+<iframe srcdoc="
+  <h3>vertical-rl</h3>
+  <div id='target' style='writing-mode: vertical-rl;' contenteditable>foo<br><br><br><br>bar</div>
+  <script>
+    window.getSelection().setBaseAndExtent(target.firstChild, 2, target.lastChild, 2);
+  </script>
+"></iframe>
+
+<iframe srcdoc="
+  <h3>vertical-rl &amp; RTL</h3>
+  <div id='target' style='writing-mode: vertical-rl; direction: rtl;' contenteditable>foo<br><br><br><br>bar</div>
+  <script>
+    window.getSelection().setBaseAndExtent(target.firstChild, 2, target.lastChild, 2);
+  </script>
+"></iframe>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-truncate-long-messages-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-truncate-long-messages-expected.txt
new file mode 100644
index 0000000..803efd6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-truncate-long-messages-expected.txt
@@ -0,0 +1,33 @@
+Tests that console logging large messages will be truncated.
+
+Setting max length to: 40
+Setting long string visible length to: 20
+Message: 0, length: 14, "a".repeat(80)
+Message: 1, length: 22, "aaaaaaaaaaaaaaaaaaaa"
+Message: 2, length: 20, aaaaaaaaaaaaaaaaaaaa
+Message: 3, length: 41, aaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbb
+Message: 4, length: 20, aaaaaaaaaaaaaaaaaaaa
+Message: 5, length: 22, "aaaaaaaaaaaaaaaaaaaa"
+Message: 6, length: 20, aaaaaaaaaaaaaaaaaaaa
+Message: 7, length: 35, foo aaaaaaaaaaaaaaaaaaaa {a: 1} bar
+Message: 8, length: 36, {a: 1} "aaaaaaaaaaaaaaaaaaaa" {b: 1}
+Link: https://chromium.org
+Message: 9, length: 41, aaaaaaaaaaaaaaaaaaaa https://chromium.org
+Link: https://chromium.org
+Message: 10, length: 41, https://chromium.org aaaaaaaaaaaaaaaaaaaa
+
+Expanding hidden texts
+Message: 0, length: 14, "a".repeat(80)
+Message: 1, length: 82, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+Message: 2, length: 80, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+Message: 3, length: 161, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+Message: 4, length: 80, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+Message: 5, length: 82, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+Message: 6, length: 80, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+Message: 7, length: 95, foo aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa {a: 1} bar
+Message: 8, length: 96, {a: 1} "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" {b: 1}
+Link: https://chromium.org
+Message: 9, length: 101, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa https://chromium.org
+Link: https://chromium.org
+Message: 10, length: 101, https://chromium.org aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-truncate-long-messages.js b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-truncate-long-messages.js
new file mode 100644
index 0000000..bd41b1a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-truncate-long-messages.js
@@ -0,0 +1,56 @@
+// Copyright 2017 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.
+
+(async function() {
+  TestRunner.addResult('Tests that console logging large messages will be truncated.\n');
+
+  await TestRunner.loadModule('console_test_runner');
+  await TestRunner.showPanel('console');
+  var consoleView = Console.ConsoleView.instance();
+
+  var maxLength = Console.ConsoleViewMessage._MaxTokenizableStringLength = 40;
+  var visibleLength = Console.ConsoleViewMessage._LongStringVisibleLength = 20;
+  var overMaxLength = maxLength * 2;
+  TestRunner.addResult(`Setting max length to: ${maxLength}`);
+  TestRunner.addResult(`Setting long string visible length to: ${visibleLength}`);
+
+  await ConsoleTestRunner.evaluateInConsolePromise(`"a".repeat(${overMaxLength})`);
+  await TestRunner.evaluateInPagePromise(`console.log("a".repeat(${overMaxLength}))`);
+  await TestRunner.evaluateInPagePromise(`console.log("a".repeat(${overMaxLength}), "b".repeat(${overMaxLength}))`);
+  await TestRunner.evaluateInPagePromise(`console.log("%s", "a".repeat(${overMaxLength}))`);
+  await TestRunner.evaluateInPagePromise(`console.log("%o", "a".repeat(${overMaxLength}))`);
+  await TestRunner.evaluateInPagePromise(`console.log("%c" + "a".repeat(${overMaxLength}), "color: green")`);
+  await TestRunner.evaluateInPagePromise(`console.log("foo %s %o bar", "a".repeat(${overMaxLength}), {a: 1})`);
+  await TestRunner.evaluateInPagePromise(`console.log({a: 1}, "a".repeat(${overMaxLength}), {b: 1})`);
+  await TestRunner.evaluateInPagePromise(`console.log("a".repeat(${overMaxLength}), "https://chromium.org")`);
+  await TestRunner.evaluateInPagePromise(`console.log("https://chromium.org", "a".repeat(${overMaxLength}))`);
+
+  dumpMessageLengths();
+
+  TestRunner.addResult('\nExpanding hidden texts');
+  consoleView._visibleViewMessages.forEach(message => {
+    message.element().querySelectorAll('.console-inline-button').forEach(button => button.click());
+  });
+
+  dumpMessageLengths();
+  TestRunner.completeTest();
+
+  function dumpMessageLengths() {
+    consoleView._visibleViewMessages.forEach((message, index) => {
+      var text = consoleMessageText(index);
+      TestRunner.addResult(`Message: ${index}, length: ${text.length}, ${text}`);
+    });
+
+    function consoleMessageText(index) {
+      var messageElement = consoleView._visibleViewMessages[index].element();
+      var anchor = messageElement.querySelector('.console-message-anchor');
+      if (anchor)
+        anchor.remove();
+      var links = messageElement.querySelectorAll('.devtools-link');
+      for (var link of links)
+        TestRunner.addResult(`Link: ${link.textContent}`);
+      return messageElement.deepTextContent();
+    }
+  }
+})();
diff --git a/third_party/WebKit/LayoutTests/platform/linux/editing/selection/selection-linebreaks-rtl-writing-modes-expected.png b/third_party/WebKit/LayoutTests/platform/linux/editing/selection/selection-linebreaks-rtl-writing-modes-expected.png
new file mode 100644
index 0000000..4e24747
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/editing/selection/selection-linebreaks-rtl-writing-modes-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/editing/selection/selection-linebreaks-rtl-writing-modes-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/editing/selection/selection-linebreaks-rtl-writing-modes-expected.txt
new file mode 100644
index 0000000..274cd0ef
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/editing/selection/selection-linebreaks-rtl-writing-modes-expected.txt
@@ -0,0 +1,125 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x580
+  LayoutBlockFlow {HTML} at (0,0) size 800x580
+    LayoutBlockFlow {BODY} at (8,16) size 784x56
+      LayoutBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 693x19
+          text run at (0,0) width 693: "This test checks that selection of linebreaks works as expected with the different directions and writing modes."
+      LayoutBlockFlow {P} at (0,36) size 784x20
+        LayoutText {#text} at (0,0) size 551x19
+          text run at (0,0) width 551: "The test passes if you can visually see the linebreaks selection in the different examples."
+layer at (18,98) size 226x226
+  LayoutIFrame (floating) {IFRAME} at (10,82) size 226x226 [border: (3px solid #000000)]
+    layer at (0,0) size 200x200
+      LayoutView at (0,0) size 200x200
+    layer at (0,0) size 200x168
+      LayoutBlockFlow {HTML} at (0,0) size 200x168.44
+        LayoutBlockFlow {BODY} at (8,18.72) size 184x141.72
+          LayoutBlockFlow {H3} at (0,0) size 184x23
+            LayoutText {#text} at (0,0) size 60x22
+              text run at (0,0) width 60: "Default"
+          LayoutBlockFlow {DIV} at (0,41.72) size 184x100
+            LayoutText {#text} at (0,0) size 21x19
+              text run at (0,0) width 21: "foo"
+            LayoutBR {BR} at (21,0) size 0x19
+            LayoutBR {BR} at (0,20) size 0x19
+            LayoutBR {BR} at (0,40) size 0x19
+            LayoutBR {BR} at (0,60) size 0x19
+            LayoutText {#text} at (0,80) size 20x19
+              text run at (0,80) width 20: "bar"
+layer at (264,98) size 226x226
+  LayoutIFrame (floating) {IFRAME} at (256,82) size 226x226 [border: (3px solid #000000)]
+    layer at (0,0) size 200x200
+      LayoutView at (0,0) size 200x200
+    layer at (0,0) size 200x168
+      LayoutBlockFlow {HTML} at (0,0) size 200x168.44
+        LayoutBlockFlow {BODY} at (8,18.72) size 184x141.72
+          LayoutBlockFlow {H3} at (0,0) size 184x23
+            LayoutText {#text} at (0,0) size 40x22
+              text run at (0,0) width 40: "RTL"
+          LayoutBlockFlow {DIV} at (0,41.72) size 184x100
+            LayoutText {#text} at (163,0) size 21x19
+              text run at (163,0) width 21: "foo"
+            LayoutBR {BR} at (163,0) size 0x19
+            LayoutBR {BR} at (184,20) size 0x19
+            LayoutBR {BR} at (184,40) size 0x19
+            LayoutBR {BR} at (184,60) size 0x19
+            LayoutText {#text} at (164,80) size 20x19
+              text run at (164,80) width 20: "bar"
+layer at (510,98) size 226x226
+  LayoutIFrame (floating) {IFRAME} at (502,82) size 226x226 [border: (3px solid #000000)]
+    layer at (0,0) size 200x200
+      LayoutView at (0,0) size 200x200
+    layer at (0,0) size 200x89
+      LayoutBlockFlow {HTML} at (0,0) size 200x89.44
+        LayoutBlockFlow {BODY} at (8,18.72) size 184x62.72
+          LayoutBlockFlow {H3} at (0,0) size 184x23
+            LayoutText {#text} at (0,0) size 79x22
+              text run at (0,0) width 79: "vertical-lr"
+          LayoutBlockFlow {DIV} at (0,41.72) size 100x21
+            LayoutText {#text} at (0,0) size 19x21
+              text run at (0,0) width 21: "foo"
+            LayoutBR {BR} at (0,21) size 19x0
+            LayoutBR {BR} at (20,0) size 19x0
+            LayoutBR {BR} at (40,0) size 19x0
+            LayoutBR {BR} at (60,0) size 19x0
+            LayoutText {#text} at (80,0) size 19x20
+              text run at (80,0) width 20: "bar"
+layer at (18,344) size 226x226
+  LayoutIFrame (floating) {IFRAME} at (10,328) size 226x226 [border: (3px solid #000000)]
+    layer at (0,0) size 200x200
+      LayoutView at (0,0) size 200x200
+    layer at (0,0) size 200x89
+      LayoutBlockFlow {HTML} at (0,0) size 200x89.44
+        LayoutBlockFlow {BODY} at (8,18.72) size 184x62.72
+          LayoutBlockFlow {H3} at (0,0) size 184x23
+            LayoutText {#text} at (0,0) size 145x22
+              text run at (0,0) width 145: "vertical-lr & RTL"
+          LayoutBlockFlow {DIV} at (0,41.72) size 100x21
+            LayoutText {#text} at (0,0) size 19x21
+              text run at (0,0) width 21: "foo"
+            LayoutBR {BR} at (0,0) size 19x0
+            LayoutBR {BR} at (20,21) size 19x0
+            LayoutBR {BR} at (40,21) size 19x0
+            LayoutBR {BR} at (60,21) size 19x0
+            LayoutText {#text} at (80,1) size 19x20
+              text run at (80,1) width 20: "bar"
+layer at (264,344) size 226x226
+  LayoutIFrame (floating) {IFRAME} at (256,328) size 226x226 [border: (3px solid #000000)]
+    layer at (0,0) size 200x200
+      LayoutView at (0,0) size 200x200
+    layer at (0,0) size 200x89
+      LayoutBlockFlow {HTML} at (0,0) size 200x89.44
+        LayoutBlockFlow {BODY} at (8,18.72) size 184x62.72
+          LayoutBlockFlow {H3} at (0,0) size 184x23
+            LayoutText {#text} at (0,0) size 79x22
+              text run at (0,0) width 79: "vertical-rl"
+          LayoutBlockFlow {DIV} at (0,41.72) size 100x21
+            LayoutText {#text} at (0,0) size 19x21
+              text run at (0,0) width 21: "foo"
+            LayoutBR {BR} at (0,21) size 19x0
+            LayoutBR {BR} at (20,0) size 19x0
+            LayoutBR {BR} at (40,0) size 19x0
+            LayoutBR {BR} at (60,0) size 19x0
+            LayoutText {#text} at (80,0) size 19x20
+              text run at (80,0) width 20: "bar"
+layer at (510,344) size 226x226
+  LayoutIFrame (floating) {IFRAME} at (502,328) size 226x226 [border: (3px solid #000000)]
+    layer at (0,0) size 200x200
+      LayoutView at (0,0) size 200x200
+    layer at (0,0) size 200x89
+      LayoutBlockFlow {HTML} at (0,0) size 200x89.44
+        LayoutBlockFlow {BODY} at (8,18.72) size 184x62.72
+          LayoutBlockFlow {H3} at (0,0) size 184x23
+            LayoutText {#text} at (0,0) size 145x22
+              text run at (0,0) width 145: "vertical-rl & RTL"
+          LayoutBlockFlow {DIV} at (0,41.72) size 100x21
+            LayoutText {#text} at (0,0) size 19x21
+              text run at (0,0) width 21: "foo"
+            LayoutBR {BR} at (0,0) size 19x0
+            LayoutBR {BR} at (20,21) size 19x0
+            LayoutBR {BR} at (40,21) size 19x0
+            LayoutBR {BR} at (60,21) size 19x0
+            LayoutText {#text} at (80,1) size 19x20
+              text run at (80,1) width 20: "bar"
diff --git a/third_party/WebKit/LayoutTests/platform/linux/editing/style/5228141-expected.png b/third_party/WebKit/LayoutTests/platform/linux/editing/style/5228141-expected.png
index da87313..5491d7b 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/editing/style/5228141-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/editing/style/5228141-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/text/selection/selection-hard-linebreak-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/text/selection/selection-hard-linebreak-expected.png
index 775a213..b37cc26 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/text/selection/selection-hard-linebreak-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/text/selection/selection-hard-linebreak-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/selection/selection-hard-linebreak-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/selection/selection-hard-linebreak-expected.png
index 15f7858..be03961f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/selection/selection-hard-linebreak-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/selection/selection-hard-linebreak-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/editing/selection/selection-linebreaks-rtl-writing-modes-expected.png b/third_party/WebKit/LayoutTests/platform/mac/editing/selection/selection-linebreaks-rtl-writing-modes-expected.png
new file mode 100644
index 0000000..004284fb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/editing/selection/selection-linebreaks-rtl-writing-modes-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/editing/selection/selection-linebreaks-rtl-writing-modes-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/editing/selection/selection-linebreaks-rtl-writing-modes-expected.txt
new file mode 100644
index 0000000..c801007
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/editing/selection/selection-linebreaks-rtl-writing-modes-expected.txt
@@ -0,0 +1,125 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x576
+  LayoutBlockFlow {HTML} at (0,0) size 800x576
+    LayoutBlockFlow {BODY} at (8,16) size 784x52
+      LayoutBlockFlow {P} at (0,0) size 784x18
+        LayoutText {#text} at (0,0) size 709x18
+          text run at (0,0) width 709: "This test checks that selection of linebreaks works as expected with the different directions and writing modes."
+      LayoutBlockFlow {P} at (0,34) size 784x18
+        LayoutText {#text} at (0,0) size 565x18
+          text run at (0,0) width 565: "The test passes if you can visually see the linebreaks selection in the different examples."
+layer at (18,94) size 226x226
+  LayoutIFrame (floating) {IFRAME} at (10,78) size 226x226 [border: (3px solid #000000)]
+    layer at (0,0) size 200x200
+      LayoutView at (0,0) size 200x200
+    layer at (0,0) size 200x157
+      LayoutBlockFlow {HTML} at (0,0) size 200x157.44
+        LayoutBlockFlow {BODY} at (8,18.72) size 184x130.72
+          LayoutBlockFlow {H3} at (0,0) size 184x22
+            LayoutText {#text} at (0,0) size 60x22
+              text run at (0,0) width 60: "Default"
+          LayoutBlockFlow {DIV} at (0,40.72) size 184x90
+            LayoutText {#text} at (0,0) size 22x18
+              text run at (0,0) width 22: "foo"
+            LayoutBR {BR} at (21,0) size 1x18
+            LayoutBR {BR} at (0,18) size 0x18
+            LayoutBR {BR} at (0,36) size 0x18
+            LayoutBR {BR} at (0,54) size 0x18
+            LayoutText {#text} at (0,72) size 21x18
+              text run at (0,72) width 21: "bar"
+layer at (264,94) size 226x226
+  LayoutIFrame (floating) {IFRAME} at (256,78) size 226x226 [border: (3px solid #000000)]
+    layer at (0,0) size 200x200
+      LayoutView at (0,0) size 200x200
+    layer at (0,0) size 200x157
+      LayoutBlockFlow {HTML} at (0,0) size 200x157.44
+        LayoutBlockFlow {BODY} at (8,18.72) size 184x130.72
+          LayoutBlockFlow {H3} at (0,0) size 184x22
+            LayoutText {#text} at (0,0) size 38x22
+              text run at (0,0) width 38: "RTL"
+          LayoutBlockFlow {DIV} at (0,40.72) size 184x90
+            LayoutText {#text} at (162,0) size 22x18
+              text run at (162,0) width 22: "foo"
+            LayoutBR {BR} at (162,0) size 1x18
+            LayoutBR {BR} at (184,18) size 0x18
+            LayoutBR {BR} at (184,36) size 0x18
+            LayoutBR {BR} at (184,54) size 0x18
+            LayoutText {#text} at (163,72) size 21x18
+              text run at (163,72) width 21: "bar"
+layer at (510,94) size 226x226
+  LayoutIFrame (floating) {IFRAME} at (502,78) size 226x226 [border: (3px solid #000000)]
+    layer at (0,0) size 200x200
+      LayoutView at (0,0) size 200x200
+    layer at (0,0) size 200x89
+      LayoutBlockFlow {HTML} at (0,0) size 200x88.77
+        LayoutBlockFlow {BODY} at (8,18.72) size 184x62.05
+          LayoutBlockFlow {H3} at (0,0) size 184x22
+            LayoutText {#text} at (0,0) size 80x22
+              text run at (0,0) width 80: "vertical-lr"
+          LayoutBlockFlow {DIV} at (0,40.72) size 90x21.33
+            LayoutText {#text} at (0,0) size 18x22
+              text run at (0,0) width 22: "foo"
+            LayoutBR {BR} at (0,21) size 18x1
+            LayoutBR {BR} at (18,0) size 18x0
+            LayoutBR {BR} at (36,0) size 18x0
+            LayoutBR {BR} at (54,0) size 18x0
+            LayoutText {#text} at (72,0) size 18x21
+              text run at (72,0) width 21: "bar"
+layer at (18,340) size 226x226
+  LayoutIFrame (floating) {IFRAME} at (10,324) size 226x226 [border: (3px solid #000000)]
+    layer at (0,0) size 200x200
+      LayoutView at (0,0) size 200x200
+    layer at (0,0) size 200x89
+      LayoutBlockFlow {HTML} at (0,0) size 200x88.77
+        LayoutBlockFlow {BODY} at (8,18.72) size 184x62.05
+          LayoutBlockFlow {H3} at (0,0) size 184x22
+            LayoutText {#text} at (0,0) size 143x22
+              text run at (0,0) width 143: "vertical-lr & RTL"
+          LayoutBlockFlow {DIV} at (0,40.72) size 90x21.33
+            LayoutText {#text} at (0,0) size 18x22
+              text run at (0,0) width 22: "foo"
+            LayoutBR {BR} at (0,0) size 18x0
+            LayoutBR {BR} at (18,21) size 18x1
+            LayoutBR {BR} at (36,21) size 18x1
+            LayoutBR {BR} at (54,21) size 18x1
+            LayoutText {#text} at (72,0) size 18x22
+              text run at (72,0) width 21: "bar"
+layer at (264,340) size 226x226
+  LayoutIFrame (floating) {IFRAME} at (256,324) size 226x226 [border: (3px solid #000000)]
+    layer at (0,0) size 200x200
+      LayoutView at (0,0) size 200x200
+    layer at (0,0) size 200x89
+      LayoutBlockFlow {HTML} at (0,0) size 200x88.77
+        LayoutBlockFlow {BODY} at (8,18.72) size 184x62.05
+          LayoutBlockFlow {H3} at (0,0) size 184x22
+            LayoutText {#text} at (0,0) size 80x22
+              text run at (0,0) width 80: "vertical-rl"
+          LayoutBlockFlow {DIV} at (0,40.72) size 90x21.33
+            LayoutText {#text} at (0,0) size 18x22
+              text run at (0,0) width 22: "foo"
+            LayoutBR {BR} at (0,21) size 18x1
+            LayoutBR {BR} at (18,0) size 18x0
+            LayoutBR {BR} at (36,0) size 18x0
+            LayoutBR {BR} at (54,0) size 18x0
+            LayoutText {#text} at (72,0) size 18x21
+              text run at (72,0) width 21: "bar"
+layer at (510,340) size 226x226
+  LayoutIFrame (floating) {IFRAME} at (502,324) size 226x226 [border: (3px solid #000000)]
+    layer at (0,0) size 200x200
+      LayoutView at (0,0) size 200x200
+    layer at (0,0) size 200x89
+      LayoutBlockFlow {HTML} at (0,0) size 200x88.77
+        LayoutBlockFlow {BODY} at (8,18.72) size 184x62.05
+          LayoutBlockFlow {H3} at (0,0) size 184x22
+            LayoutText {#text} at (0,0) size 143x22
+              text run at (0,0) width 143: "vertical-rl & RTL"
+          LayoutBlockFlow {DIV} at (0,40.72) size 90x21.33
+            LayoutText {#text} at (0,0) size 18x22
+              text run at (0,0) width 22: "foo"
+            LayoutBR {BR} at (0,0) size 18x0
+            LayoutBR {BR} at (18,21) size 18x1
+            LayoutBR {BR} at (36,21) size 18x1
+            LayoutBR {BR} at (54,21) size 18x1
+            LayoutText {#text} at (72,0) size 18x22
+              text run at (72,0) width 21: "bar"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/editing/style/5228141-expected.png b/third_party/WebKit/LayoutTests/platform/mac/editing/style/5228141-expected.png
index db80184b..041906d6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/editing/style/5228141-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/editing/style/5228141-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/selection/selection-hard-linebreak-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/selection/selection-hard-linebreak-expected.png
index 0a0f330e..cf8ff51 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/text/selection/selection-hard-linebreak-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/selection/selection-hard-linebreak-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/selection/selection-change-in-iframe-with-relative-parent-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/selection/selection-change-in-iframe-with-relative-parent-expected.png
index 468c93c1..d7a6acb4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/selection/selection-change-in-iframe-with-relative-parent-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/selection/selection-change-in-iframe-with-relative-parent-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/editing/selection/selection-linebreaks-rtl-writing-modes-expected.png b/third_party/WebKit/LayoutTests/platform/win/editing/selection/selection-linebreaks-rtl-writing-modes-expected.png
new file mode 100644
index 0000000..5b668d7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/editing/selection/selection-linebreaks-rtl-writing-modes-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/editing/selection/selection-linebreaks-rtl-writing-modes-expected.txt b/third_party/WebKit/LayoutTests/platform/win/editing/selection/selection-linebreaks-rtl-writing-modes-expected.txt
new file mode 100644
index 0000000..a475662
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/editing/selection/selection-linebreaks-rtl-writing-modes-expected.txt
@@ -0,0 +1,125 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x580
+  LayoutBlockFlow {HTML} at (0,0) size 800x580
+    LayoutBlockFlow {BODY} at (8,16) size 784x56
+      LayoutBlockFlow {P} at (0,0) size 784x20
+        LayoutText {#text} at (0,0) size 661x19
+          text run at (0,0) width 661: "This test checks that selection of linebreaks works as expected with the different directions and writing modes."
+      LayoutBlockFlow {P} at (0,36) size 784x20
+        LayoutText {#text} at (0,0) size 521x19
+          text run at (0,0) width 521: "The test passes if you can visually see the linebreaks selection in the different examples."
+layer at (18,98) size 226x226
+  LayoutIFrame (floating) {IFRAME} at (10,82) size 226x226 [border: (3px solid #000000)]
+    layer at (0,0) size 200x200
+      LayoutView at (0,0) size 200x200
+    layer at (0,0) size 200x168
+      LayoutBlockFlow {HTML} at (0,0) size 200x168.44
+        LayoutBlockFlow {BODY} at (8,18.72) size 184x141.72
+          LayoutBlockFlow {H3} at (0,0) size 184x23
+            LayoutText {#text} at (0,0) size 60x22
+              text run at (0,0) width 60: "Default"
+          LayoutBlockFlow {DIV} at (0,41.72) size 184x100
+            LayoutText {#text} at (0,0) size 20x19
+              text run at (0,0) width 20: "foo"
+            LayoutBR {BR} at (20,0) size 0x19
+            LayoutBR {BR} at (0,20) size 0x19
+            LayoutBR {BR} at (0,40) size 0x19
+            LayoutBR {BR} at (0,60) size 0x19
+            LayoutText {#text} at (0,80) size 20x19
+              text run at (0,80) width 20: "bar"
+layer at (264,98) size 226x226
+  LayoutIFrame (floating) {IFRAME} at (256,82) size 226x226 [border: (3px solid #000000)]
+    layer at (0,0) size 200x200
+      LayoutView at (0,0) size 200x200
+    layer at (0,0) size 200x168
+      LayoutBlockFlow {HTML} at (0,0) size 200x168.44
+        LayoutBlockFlow {BODY} at (8,18.72) size 184x141.72
+          LayoutBlockFlow {H3} at (0,0) size 184x23
+            LayoutText {#text} at (0,0) size 39x22
+              text run at (0,0) width 39: "RTL"
+          LayoutBlockFlow {DIV} at (0,41.72) size 184x100
+            LayoutText {#text} at (164,0) size 20x19
+              text run at (164,0) width 20: "foo"
+            LayoutBR {BR} at (164,0) size 0x19
+            LayoutBR {BR} at (184,20) size 0x19
+            LayoutBR {BR} at (184,40) size 0x19
+            LayoutBR {BR} at (184,60) size 0x19
+            LayoutText {#text} at (164,80) size 20x19
+              text run at (164,80) width 20: "bar"
+layer at (510,98) size 226x226
+  LayoutIFrame (floating) {IFRAME} at (502,82) size 226x226 [border: (3px solid #000000)]
+    layer at (0,0) size 200x200
+      LayoutView at (0,0) size 200x200
+    layer at (0,0) size 200x88
+      LayoutBlockFlow {HTML} at (0,0) size 200x88.44
+        LayoutBlockFlow {BODY} at (8,18.72) size 184x61.72
+          LayoutBlockFlow {H3} at (0,0) size 184x23
+            LayoutText {#text} at (0,0) size 80x22
+              text run at (0,0) width 80: "vertical-lr"
+          LayoutBlockFlow {DIV} at (0,41.72) size 100x20
+            LayoutText {#text} at (0,0) size 19x20
+              text run at (0,0) width 20: "foo"
+            LayoutBR {BR} at (0,20) size 19x0
+            LayoutBR {BR} at (20,0) size 19x0
+            LayoutBR {BR} at (40,0) size 19x0
+            LayoutBR {BR} at (60,0) size 19x0
+            LayoutText {#text} at (80,0) size 19x20
+              text run at (80,0) width 20: "bar"
+layer at (18,344) size 226x226
+  LayoutIFrame (floating) {IFRAME} at (10,328) size 226x226 [border: (3px solid #000000)]
+    layer at (0,0) size 200x200
+      LayoutView at (0,0) size 200x200
+    layer at (0,0) size 200x88
+      LayoutBlockFlow {HTML} at (0,0) size 200x88.44
+        LayoutBlockFlow {BODY} at (8,18.72) size 184x61.72
+          LayoutBlockFlow {H3} at (0,0) size 184x23
+            LayoutText {#text} at (0,0) size 145x22
+              text run at (0,0) width 145: "vertical-lr & RTL"
+          LayoutBlockFlow {DIV} at (0,41.72) size 100x20
+            LayoutText {#text} at (0,0) size 19x20
+              text run at (0,0) width 20: "foo"
+            LayoutBR {BR} at (0,0) size 19x0
+            LayoutBR {BR} at (20,20) size 19x0
+            LayoutBR {BR} at (40,20) size 19x0
+            LayoutBR {BR} at (60,20) size 19x0
+            LayoutText {#text} at (80,0) size 19x20
+              text run at (80,0) width 20: "bar"
+layer at (264,344) size 226x226
+  LayoutIFrame (floating) {IFRAME} at (256,328) size 226x226 [border: (3px solid #000000)]
+    layer at (0,0) size 200x200
+      LayoutView at (0,0) size 200x200
+    layer at (0,0) size 200x88
+      LayoutBlockFlow {HTML} at (0,0) size 200x88.44
+        LayoutBlockFlow {BODY} at (8,18.72) size 184x61.72
+          LayoutBlockFlow {H3} at (0,0) size 184x23
+            LayoutText {#text} at (0,0) size 80x22
+              text run at (0,0) width 80: "vertical-rl"
+          LayoutBlockFlow {DIV} at (0,41.72) size 100x20
+            LayoutText {#text} at (0,0) size 19x20
+              text run at (0,0) width 20: "foo"
+            LayoutBR {BR} at (0,20) size 19x0
+            LayoutBR {BR} at (20,0) size 19x0
+            LayoutBR {BR} at (40,0) size 19x0
+            LayoutBR {BR} at (60,0) size 19x0
+            LayoutText {#text} at (80,0) size 19x20
+              text run at (80,0) width 20: "bar"
+layer at (510,344) size 226x226
+  LayoutIFrame (floating) {IFRAME} at (502,328) size 226x226 [border: (3px solid #000000)]
+    layer at (0,0) size 200x200
+      LayoutView at (0,0) size 200x200
+    layer at (0,0) size 200x88
+      LayoutBlockFlow {HTML} at (0,0) size 200x88.44
+        LayoutBlockFlow {BODY} at (8,18.72) size 184x61.72
+          LayoutBlockFlow {H3} at (0,0) size 184x23
+            LayoutText {#text} at (0,0) size 145x22
+              text run at (0,0) width 145: "vertical-rl & RTL"
+          LayoutBlockFlow {DIV} at (0,41.72) size 100x20
+            LayoutText {#text} at (0,0) size 19x20
+              text run at (0,0) width 20: "foo"
+            LayoutBR {BR} at (0,0) size 19x0
+            LayoutBR {BR} at (20,20) size 19x0
+            LayoutBR {BR} at (40,20) size 19x0
+            LayoutBR {BR} at (60,20) size 19x0
+            LayoutText {#text} at (80,0) size 19x20
+              text run at (80,0) width 20: "bar"
diff --git a/third_party/WebKit/LayoutTests/platform/win/editing/style/5228141-expected.png b/third_party/WebKit/LayoutTests/platform/win/editing/style/5228141-expected.png
index a77d1d7..2f5240c 100644
--- a/third_party/WebKit/LayoutTests/platform/win/editing/style/5228141-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/editing/style/5228141-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/text/selection/selection-hard-linebreak-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/text/selection/selection-hard-linebreak-expected.png
index de0f659..4af29ac 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/text/selection/selection-hard-linebreak-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/text/selection/selection-hard-linebreak-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/selection/selection-change-in-iframe-with-relative-parent-expected.png b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/selection/selection-change-in-iframe-with-relative-parent-expected.png
index 667a5fb..4dd6f49aa 100644
--- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/selection/selection-change-in-iframe-with-relative-parent-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/selection/selection-change-in-iframe-with-relative-parent-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/text/selection/selection-hard-linebreak-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/text/selection/selection-hard-linebreak-expected.png
index 1b12ba9..ae5adf86 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/text/selection/selection-hard-linebreak-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/text/selection/selection-hard-linebreak-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/selection/selection-change-in-iframe-with-relative-parent-expected.png b/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/selection/selection-change-in-iframe-with-relative-parent-expected.png
new file mode 100644
index 0000000..4dd6f49aa
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/selection/selection-change-in-iframe-with-relative-parent-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/selection/selection-change-in-iframe-with-relative-parent-expected.txt b/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/selection/selection-change-in-iframe-with-relative-parent-expected.txt
index 78b78bf8..26aa549 100644
--- a/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/selection/selection-change-in-iframe-with-relative-parent-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/selection/selection-change-in-iframe-with-relative-parent-expected.txt
@@ -35,6 +35,16 @@
           "object": "InlineTextBox '\n'",
           "rect": [48, 198, 10, 10],
           "reason": "appeared"
+        },
+        {
+          "object": "InlineTextBox '\n'",
+          "rect": [18, 228, 10, 10],
+          "reason": "appeared"
+        },
+        {
+          "object": "InlineTextBox '\n'",
+          "rect": [18, 208, 10, 10],
+          "reason": "appeared"
         }
       ]
     }
diff --git a/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImplTest.cpp b/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImplTest.cpp
index 7e0df3b4..a6f6a08 100644
--- a/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImplTest.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/NativeValueTraitsImplTest.cpp
@@ -37,18 +37,10 @@
   DummyExceptionStateForTesting exception_state;
   v8::Local<v8::Function> function =
       v8::Function::New(scope.GetContext(), nullptr).ToLocalChecked();
-#if defined(OFFICIAL_BUILD)
-  // crbug.com/779820
-  // Official builds have an issue that stripts the CHECK strings despite that
-  // the strings are referenced in tests.
-  ASSERT_DEATH(NativeValueTraits<V8TestSequenceCallback>::NativeValue(
-                   scope.GetIsolate(), function, exception_state),
-               "");
-#else
-  ASSERT_DEATH(NativeValueTraits<V8TestSequenceCallback>::NativeValue(
-                   scope.GetIsolate(), function, exception_state),
-               "NativeValueTraits<CallbackFunctionBase>::NativeValue");
-#endif
+  ASSERT_DEATH_IF_SUPPORTED(
+      NativeValueTraits<V8TestSequenceCallback>::NativeValue(
+          scope.GetIsolate(), function, exception_state),
+      "");
 }
 
 void ThrowException(v8::Local<v8::Name>,
diff --git a/third_party/WebKit/Source/core/BUILD.gn b/third_party/WebKit/Source/core/BUILD.gn
index 438f511..d70a29c 100644
--- a/third_party/WebKit/Source/core/BUILD.gn
+++ b/third_party/WebKit/Source/core/BUILD.gn
@@ -1663,6 +1663,7 @@
     "layout/ng/geometry/ng_physical_offset_rect_test.cc",
     "layout/ng/geometry/ng_physical_offset_test.cc",
     "layout/ng/geometry/ng_physical_rect_test.cc",
+    "layout/ng/inline/ng_inline_fragment_traversal_test.cc",
     "layout/ng/inline/ng_inline_items_builder_test.cc",
     "layout/ng/inline/ng_inline_layout_algorithm_test.cc",
     "layout/ng/inline/ng_inline_node_test.cc",
diff --git a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
index 4208628..75833f9 100644
--- a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
+++ b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
@@ -219,7 +219,7 @@
           child->GetLineLayoutItem().StyleRef(IsFirstLineStyle());
       if (child_style.LetterSpacing() < 0 || child_style.TextShadow() ||
           child_style.GetTextEmphasisMark() != TextEmphasisMark::kNone ||
-          child_style.TextStrokeWidth())
+          child_style.TextStrokeWidth() || child->IsLineBreak())
         child->ClearKnownToHaveNoOverflow();
     } else if (child->GetLineLayoutItem().IsAtomicInlineLevel()) {
       LineLayoutBox box = LineLayoutBox(child->GetLineLayoutItem());
@@ -1210,19 +1210,22 @@
 
     if (curr->GetLineLayoutItem().IsText()) {
       InlineTextBox* text = ToInlineTextBox(curr);
-      LineLayoutText rt = text->GetLineLayoutItem();
-      if (rt.IsBR())
-        continue;
       LayoutRect text_box_overflow(text->LogicalFrameRect());
-      if (text_box_data_map.IsEmpty()) {
-        // An empty glyph map means that we're computing overflow without
-        // a layout, so calculate the glyph overflow on the fly.
-        GlyphOverflowAndFallbackFontsMap glyph_overflow_for_text;
-        ComputeGlyphOverflow(text, rt, glyph_overflow_for_text);
-        AddTextBoxVisualOverflow(text, glyph_overflow_for_text,
-                                 text_box_overflow);
+      if (text->IsLineBreak()) {
+        text_box_overflow.SetWidth(
+            LayoutUnit(text_box_overflow.Width() + text->NewlineSpaceWidth()));
       } else {
-        AddTextBoxVisualOverflow(text, text_box_data_map, text_box_overflow);
+        if (text_box_data_map.IsEmpty()) {
+          // An empty glyph map means that we're computing overflow without
+          // a layout, so calculate the glyph overflow on the fly.
+          GlyphOverflowAndFallbackFontsMap glyph_overflow_for_text;
+          ComputeGlyphOverflow(text, text->GetLineLayoutItem(),
+                               glyph_overflow_for_text);
+          AddTextBoxVisualOverflow(text, glyph_overflow_for_text,
+                                   text_box_overflow);
+        } else {
+          AddTextBoxVisualOverflow(text, text_box_data_map, text_box_overflow);
+        }
       }
       logical_visual_overflow.Unite(text_box_overflow);
     } else if (curr->GetLineLayoutItem().IsLayoutInline()) {
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_fragment_iterator.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_fragment_iterator.cc
index 1d2a053f..a251a62 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_fragment_iterator.cc
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_fragment_iterator.cc
@@ -2,35 +2,33 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// TODO(xiaochengh): Rename this file into ng_inline_fragment_traversal.cc
+
 #include "core/layout/ng/inline/ng_inline_fragment_iterator.h"
 
 #include "core/layout/LayoutObject.h"
 #include "core/layout/ng/ng_physical_box_fragment.h"
-#include "platform/wtf/HashMap.h"
 
 namespace blink {
 
-NGInlineFragmentIterator::NGInlineFragmentIterator(
-    const NGPhysicalBoxFragment& box,
-    const LayoutObject* filter) {
-  DCHECK(filter);
+namespace {
 
-  CollectInlineFragments(box, {}, filter, &results_);
-}
+using Result = NGPhysicalFragmentWithOffset;
 
-// Create a map from a LayoutObject to a vector of PhysicalFragment and its
-// offset to the container box. This is done by collecting inline child
-// fragments of the container fragment, while accumulating the offset to the
-// container box.
-void NGInlineFragmentIterator::CollectInlineFragments(
-    const NGPhysicalContainerFragment& container,
-    NGPhysicalOffset offset_to_container_box,
-    const LayoutObject* filter,
-    Results* results) {
+// Traverse the subtree of |container|, and collect the fragments satisfying
+// |filter| into the |results| vector. Guarantees to call |filter.AddOnEnter()|
+// for all fragments in preorder, and call |filter.RemoveOnExit()| on all
+// fragments in postorder. A fragment is collected if |AddOnEnter()| returns
+// true and |RemoveOnExit()| returns false on it.
+template <typename Filter, size_t inline_capacity>
+void CollectInlineFragments(const NGPhysicalContainerFragment& container,
+                            NGPhysicalOffset offset_to_container_box,
+                            Filter& filter,
+                            Vector<Result, inline_capacity>* results) {
   for (const auto& child : container.Children()) {
     NGPhysicalOffset child_offset = child->Offset() + offset_to_container_box;
 
-    if (filter == child->GetLayoutObject()) {
+    if (filter.AddOnEnter(child.get())) {
       results->push_back(
           NGPhysicalFragmentWithOffset{child.get(), child_offset});
     }
@@ -41,7 +39,136 @@
       CollectInlineFragments(ToNGPhysicalContainerFragment(*child),
                              child_offset, filter, results);
     }
+
+    if (filter.RemoveOnExit(child.get())) {
+      DCHECK(results->size());
+      DCHECK_EQ(results->back().fragment, child.get());
+      results->pop_back();
+    }
   }
 }
 
+// The filter for CollectInlineFragments() collecting all fragments traversed.
+class AddAllFilter {
+ public:
+  bool AddOnEnter(const NGPhysicalFragment*) const { return true; }
+  bool RemoveOnExit(const NGPhysicalFragment*) const { return false; }
+};
+
+// The filter for CollectInlineFragments() collecting fragments generated from
+// the given LayoutObject.
+class LayoutObjectFilter {
+ public:
+  explicit LayoutObjectFilter(const LayoutObject* layout_object)
+      : layout_object_(layout_object) {
+    DCHECK(layout_object);
+  }
+
+  bool AddOnEnter(const NGPhysicalFragment* fragment) const {
+    return fragment->GetLayoutObject() == layout_object_;
+  }
+  bool RemoveOnExit(const NGPhysicalFragment*) const { return false; }
+
+ private:
+  const LayoutObject* layout_object_;
+};
+
+// The filter for CollectInlineFragments() collecting inclusive ancestors of the
+// given fragment with the algorithm that, |fragment| is an ancestor of |target|
+// if and only if both of the following are true:
+// - |fragment| precedes |target| in preorder traversal
+// - |fragment| succeeds |target| in postorder traversal
+class InclusiveAncestorFilter {
+ public:
+  explicit InclusiveAncestorFilter(const NGPhysicalFragment& target)
+      : target_(&target) {}
+
+  bool AddOnEnter(const NGPhysicalFragment* fragment) {
+    if (fragment == target_)
+      has_entered_target_ = true;
+    ancestors_precede_in_preorder_.push_back(!has_entered_target_);
+    return true;
+  }
+
+  bool RemoveOnExit(const NGPhysicalFragment* fragment) {
+    if (fragment != target_) {
+      const bool precedes_in_preorder = ancestors_precede_in_preorder_.back();
+      ancestors_precede_in_preorder_.pop_back();
+      return !precedes_in_preorder || !has_exited_target_;
+    }
+    has_exited_target_ = true;
+    ancestors_precede_in_preorder_.pop_back();
+    return false;
+  }
+
+ private:
+  const NGPhysicalFragment* target_;
+
+  bool has_entered_target_ = false;
+  bool has_exited_target_ = false;
+
+  // For each currently entered but not-yet-exited fragment, stores a boolean of
+  // whether it precedes |target_| in preorder.
+  Vector<bool> ancestors_precede_in_preorder_;
+};
+
+}  // namespace
+
+NGInlineFragmentIterator::NGInlineFragmentIterator(
+    const NGPhysicalBoxFragment& box,
+    const LayoutObject* layout_object) {
+  results_ = NGInlineFragmentTraversal::SelfFragmentsOf(box, layout_object);
+}
+
+// static
+Vector<Result, 1> NGInlineFragmentTraversal::SelfFragmentsOf(
+    const NGPhysicalContainerFragment& container,
+    const LayoutObject* layout_object) {
+  LayoutObjectFilter filter(layout_object);
+  Vector<Result, 1> results;
+  CollectInlineFragments(container, {}, filter, &results);
+  return results;
+}
+
+// static
+Vector<Result> NGInlineFragmentTraversal::DescendantsOf(
+    const NGPhysicalContainerFragment& container) {
+  AddAllFilter add_all;
+  Vector<Result> results;
+  CollectInlineFragments(container, {}, add_all, &results);
+  return results;
+}
+
+// static
+Vector<Result> NGInlineFragmentTraversal::InclusiveDescendantsOf(
+    const NGPhysicalFragment& root) {
+  Vector<Result> results =
+      root.IsContainer() ? DescendantsOf(ToNGPhysicalContainerFragment(root))
+                         : Vector<Result>();
+  results.push_front(Result{&root, {}});
+  return results;
+}
+
+// static
+Vector<Result> NGInlineFragmentTraversal::InclusiveAncestorsOf(
+    const NGPhysicalContainerFragment& container,
+    const NGPhysicalFragment& target) {
+  InclusiveAncestorFilter inclusive_ancestors_of(target);
+  Vector<Result> results;
+  CollectInlineFragments(container, {}, inclusive_ancestors_of, &results);
+  std::reverse(results.begin(), results.end());
+  return results;
+}
+
+// static
+Vector<Result> NGInlineFragmentTraversal::AncestorsOf(
+    const NGPhysicalContainerFragment& container,
+    const NGPhysicalFragment& target) {
+  Vector<Result> results = InclusiveAncestorsOf(container, target);
+  DCHECK(results.size());
+  DCHECK_EQ(results.front().fragment, &target);
+  results.erase(results.begin());
+  return results;
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_fragment_iterator.h b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_fragment_iterator.h
index 818de04..431309e 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_fragment_iterator.h
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_fragment_iterator.h
@@ -5,6 +5,8 @@
 #ifndef NGInlineFragmentIterator_h
 #define NGInlineFragmentIterator_h
 
+// TODO(xiaochengh): Rename this file into ng_inline_fragment_traversal.h
+
 #include "core/CoreExport.h"
 #include "core/layout/ng/ng_physical_fragment.h"
 #include "platform/wtf/Allocator.h"
@@ -15,7 +17,43 @@
 class LayoutObject;
 class NGPhysicalBoxFragment;
 class NGPhysicalContainerFragment;
-struct NGPhysicalOffset;
+
+// Utility class for traversing the physical fragment tree.
+class CORE_EXPORT NGInlineFragmentTraversal {
+  STATIC_ONLY(NGInlineFragmentTraversal);
+
+ public:
+  // Return list of ancestors from |target| to |container|. Offsets are relative
+  // to |container|.
+  static Vector<NGPhysicalFragmentWithOffset> AncestorsOf(
+      const NGPhysicalContainerFragment& container,
+      const NGPhysicalFragment& target);
+
+  // Return list inclusive ancestors from |target| to |container|. Offsets are
+  // relative to |container|.
+  static Vector<NGPhysicalFragmentWithOffset> InclusiveAncestorsOf(
+      const NGPhysicalContainerFragment& container,
+      const NGPhysicalFragment& target);
+
+  // Returns list of descendants in preorder. Offsets are relative to
+  // specified fragment.
+  static Vector<NGPhysicalFragmentWithOffset> DescendantsOf(
+      const NGPhysicalContainerFragment&);
+
+  // Returns list of inclusive descendants in preorder. Offsets are relative to
+  // specified fragment.
+  static Vector<NGPhysicalFragmentWithOffset> InclusiveDescendantsOf(
+      const NGPhysicalFragment&);
+
+  // Returns list of inline fragments produced from the specified LayoutObject.
+  // The search is restricted in the subtree of |container|.
+  static Vector<NGPhysicalFragmentWithOffset, 1> SelfFragmentsOf(
+      const NGPhysicalContainerFragment& container,
+      const LayoutObject* target);
+};
+
+// TODO(xiaochengh): Convert clients of NGInlineFragmentIterator to use
+// NGInlineFragmentTraversal::SelfFragmentsOf().
 
 // Iterate through inline descendant fragments.
 class CORE_EXPORT NGInlineFragmentIterator {
@@ -33,11 +71,6 @@
   Results::const_iterator end() const { return results_.end(); }
 
  private:
-  static void CollectInlineFragments(const NGPhysicalContainerFragment&,
-                                     NGPhysicalOffset offset_to_container_box,
-                                     const LayoutObject* filter,
-                                     Results*);
-
   Results results_;
 };
 
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_fragment_traversal_test.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_fragment_traversal_test.cc
new file mode 100644
index 0000000..47d90fa
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_fragment_traversal_test.cc
@@ -0,0 +1,154 @@
+// Copyright 2017 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 "core/layout/ng/inline/ng_inline_fragment_iterator.h"
+
+#include "core/layout/ng/inline/ng_physical_text_fragment.h"
+#include "core/layout/ng/ng_layout_test.h"
+#include "core/layout/ng/ng_physical_box_fragment.h"
+
+namespace blink {
+
+class NGInlineFragmentTraversalTest
+    : public NGLayoutTest,
+      private ScopedLayoutNGPaintFragmentsForTest {
+ public:
+  NGInlineFragmentTraversalTest()
+      : NGLayoutTest(), ScopedLayoutNGPaintFragmentsForTest(true) {}
+
+ protected:
+  const NGPhysicalBoxFragment& GetRootFragmentById(const char* id) const {
+    const Element* element = GetElementById(id);
+    DCHECK(element) << id;
+    const LayoutObject* layout_object = element->GetLayoutObject();
+    DCHECK(layout_object) << element;
+    DCHECK(layout_object->IsLayoutBlockFlow()) << element;
+    DCHECK(ToLayoutBlockFlow(layout_object)->CurrentFragment()) << element;
+    return *ToLayoutBlockFlow(layout_object)->CurrentFragment();
+  }
+
+  const NGPhysicalFragment& GetFragmentOfNode(
+      const NGPhysicalContainerFragment& container,
+      const Node* node) const {
+    const LayoutObject* layout_object = node->GetLayoutObject();
+    auto fragments =
+        NGInlineFragmentTraversal::SelfFragmentsOf(container, layout_object);
+    return *fragments.front().fragment;
+  }
+};
+
+#define EXPECT_NEXT_BOX(iter, id)                                           \
+  {                                                                         \
+    const auto& current = *iter++;                                          \
+    EXPECT_TRUE(current.fragment->IsBox()) << current.fragment->ToString(); \
+    EXPECT_EQ(GetLayoutObjectByElementId(id),                               \
+              current.fragment->GetLayoutObject());                         \
+  }
+
+#define EXPECT_NEXT_LINE_BOX(iter)             \
+  {                                            \
+    const auto& current = *iter++;             \
+    EXPECT_TRUE(current.fragment->IsLineBox()) \
+        << current.fragment->ToString();       \
+  }
+
+#define EXPECT_NEXT_TEXT(iter, content)                                      \
+  {                                                                          \
+    const auto& current = *iter++;                                           \
+    EXPECT_TRUE(current.fragment->IsText()) << current.fragment->ToString(); \
+    EXPECT_EQ(content, ToNGPhysicalTextFragment(current.fragment)->Text());  \
+  }
+
+TEST_F(NGInlineFragmentTraversalTest, DescendantsOf) {
+  SetBodyInnerHTML(
+      "<style>* { border: 1px solid}</style>"
+      "<div id=t>foo<b id=b>bar</b><br>baz</div>");
+  const auto descendants =
+      NGInlineFragmentTraversal::DescendantsOf(GetRootFragmentById("t"));
+  auto iter = descendants.begin();
+
+  EXPECT_NEXT_LINE_BOX(iter);
+  EXPECT_NEXT_TEXT(iter, "foo");
+  EXPECT_NEXT_BOX(iter, "b");
+  EXPECT_NEXT_TEXT(iter, "bar");
+  EXPECT_NEXT_TEXT(iter, "\n");
+  EXPECT_NEXT_LINE_BOX(iter);
+  EXPECT_NEXT_TEXT(iter, "baz");
+  EXPECT_EQ(iter, descendants.end());
+}
+
+TEST_F(NGInlineFragmentTraversalTest, InclusiveDescendantsOf) {
+  SetBodyInnerHTML(
+      "<style>* { border: 1px solid}</style>"
+      "<div id=t>foo<b id=b>bar</b><br>baz</div>");
+  auto descendants = NGInlineFragmentTraversal::InclusiveDescendantsOf(
+      GetRootFragmentById("t"));
+  auto iter = descendants.begin();
+
+  EXPECT_NEXT_BOX(iter, "t");
+  EXPECT_NEXT_LINE_BOX(iter);
+  EXPECT_NEXT_TEXT(iter, "foo");
+  EXPECT_NEXT_BOX(iter, "b");
+  EXPECT_NEXT_TEXT(iter, "bar");
+  EXPECT_NEXT_TEXT(iter, "\n");
+  EXPECT_NEXT_LINE_BOX(iter);
+  EXPECT_NEXT_TEXT(iter, "baz");
+  EXPECT_EQ(iter, descendants.end());
+}
+
+TEST_F(NGInlineFragmentTraversalTest, SelfFragmentsOf) {
+  SetBodyInnerHTML(
+      "<style>* { border: 1px solid}</style>"
+      "<div id=t>foo<b id=filter>bar<br>baz</b>bla</div>");
+  const auto descendants = NGInlineFragmentTraversal::SelfFragmentsOf(
+      GetRootFragmentById("t"), GetLayoutObjectByElementId("filter"));
+  auto iter = descendants.begin();
+
+  // <b> generates two box fragments since its content is in two lines.
+  EXPECT_NEXT_BOX(iter, "filter");
+  EXPECT_NEXT_BOX(iter, "filter");
+  EXPECT_EQ(iter, descendants.end());
+}
+
+TEST_F(NGInlineFragmentTraversalTest, AncestorsOf) {
+  SetBodyInnerHTML(
+      "<style>* { border: 1px solid}</style>"
+      "<div id=t>x"
+      "<b id=b>y<i id=i>z<u id=target>foo</u>z</i>y</b>"
+      "x</div>");
+  const NGPhysicalContainerFragment& root = GetRootFragmentById("t");
+  const NGPhysicalFragment& target =
+      GetFragmentOfNode(root, GetElementById("target")->firstChild());
+  auto ancestors = NGInlineFragmentTraversal::AncestorsOf(root, target);
+  auto iter = ancestors.begin();
+
+  EXPECT_NEXT_BOX(iter, "target");
+  EXPECT_NEXT_BOX(iter, "i");
+  EXPECT_NEXT_BOX(iter, "b");
+  EXPECT_NEXT_LINE_BOX(iter);
+  EXPECT_EQ(iter, ancestors.end());
+}
+
+TEST_F(NGInlineFragmentTraversalTest, InclusiveAncestorsOf) {
+  SetBodyInnerHTML(
+      "<style>* { border: 1px solid}</style>"
+      "<div id=t>x"
+      "<b id=b>y<i id=i>z<u id=target>foo</u>z</i>y</b>"
+      "x</div>");
+  const NGPhysicalContainerFragment& root = GetRootFragmentById("t");
+  const NGPhysicalFragment& target =
+      GetFragmentOfNode(root, GetElementById("target")->firstChild());
+  auto ancestors =
+      NGInlineFragmentTraversal::InclusiveAncestorsOf(root, target);
+  auto iter = ancestors.begin();
+
+  EXPECT_NEXT_TEXT(iter, "foo");
+  EXPECT_NEXT_BOX(iter, "target");
+  EXPECT_NEXT_BOX(iter, "i");
+  EXPECT_NEXT_BOX(iter, "b");
+  EXPECT_NEXT_LINE_BOX(iter);
+  EXPECT_EQ(iter, ancestors.end());
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_length_utils_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_length_utils_test.cc
index 244bad3..e793290 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_length_utils_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_length_utils_test.cc
@@ -105,9 +105,10 @@
   EXPECT_EQ(LayoutUnit(200),
             ResolveInlineLength(Length(kFitContent),
                                 LengthResolveType::kContentSize, sizes));
-#ifndef NDEBUG
+
+#if DCHECK_IS_ON()
   // This should fail a DCHECK.
-  EXPECT_DEATH(ResolveInlineLength(Length(kFitContent)), "Check failed");
+  EXPECT_DEATH_IF_SUPPORTED(ResolveInlineLength(Length(kFitContent)), "");
 #endif
 }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js b/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js
index 9cb8e4f..569437cd 100644
--- a/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js
+++ b/third_party/WebKit/Source/devtools/front_end/console/ConsoleViewMessage.js
@@ -1300,6 +1300,8 @@
    * @return {!DocumentFragment}
    */
   static _linkifyWithCustomLinkifier(string, linkifier) {
+    if (string.length > Console.ConsoleViewMessage._MaxTokenizableStringLength)
+      return createExpandableFragment(string);
     var container = createDocumentFragment();
     var tokens = this._tokenizeMessageText(string);
     for (var token of tokens) {
@@ -1321,6 +1323,31 @@
       }
     }
     return container;
+
+    /**
+     * @param {string} text
+     * @return {!DocumentFragment}
+     */
+    function createExpandableFragment(text) {
+      var fragment = createDocumentFragment();
+      fragment.textContent = text.slice(0, Console.ConsoleViewMessage._LongStringVisibleLength);
+      var hiddenText = text.slice(Console.ConsoleViewMessage._LongStringVisibleLength);
+
+      var expandButton = fragment.createChild('span', 'console-inline-button');
+      expandButton.setAttribute('data-text', ls`Show ${Number.withThousandsSeparator(hiddenText.length)} more`);
+      expandButton.addEventListener('click', () => {
+        if (expandButton.parentElement)
+          expandButton.parentElement.insertBefore(createTextNode(hiddenText), expandButton);
+        expandButton.remove();
+      });
+
+      var copyButton = fragment.createChild('span', 'console-inline-button');
+      copyButton.setAttribute('data-text', ls`Copy`);
+      copyButton.addEventListener('click', () => {
+        InspectorFrontendHost.copyText(text);
+      });
+      return fragment;
+    }
   }
 
   /**
@@ -1463,3 +1490,5 @@
 Console.ConsoleViewMessage.MaxLengthForLinks = 40;
 
 Console.ConsoleViewMessage._MaxTokenizableStringLength = 10000;
+
+Console.ConsoleViewMessage._LongStringVisibleLength = 5000;
diff --git a/third_party/WebKit/Source/devtools/front_end/console/consoleView.css b/third_party/WebKit/Source/devtools/front_end/console/consoleView.css
index c476c22..bd105f77 100644
--- a/third_party/WebKit/Source/devtools/front_end/console/consoleView.css
+++ b/third_party/WebKit/Source/devtools/front_end/console/consoleView.css
@@ -406,4 +406,25 @@
 
 .console-message-expand-icon {
     margin-bottom: -2px;
-}
\ No newline at end of file
+}
+
+.console-inline-button {
+    background-color: #dedede;
+    padding: 2px 4px;
+    margin: 0 2px;
+    color: #333;
+    cursor: pointer;
+    border-radius: 3px;
+    font-size: 12px;
+    font-family: sans-serif;
+    white-space: nowrap;
+    display: inline-block;
+}
+
+.console-inline-button::after {
+    content: attr(data-text);
+}
+
+.console-inline-button:hover {
+    background-color: #d5d5d5;
+}
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioContextTest.cpp b/third_party/WebKit/Source/modules/webaudio/AudioContextTest.cpp
index 8dda2fc..6f2409e 100644
--- a/third_party/WebKit/Source/modules/webaudio/AudioContextTest.cpp
+++ b/third_party/WebKit/Source/modules/webaudio/AudioContextTest.cpp
@@ -8,7 +8,6 @@
 
 #include "core/dom/Document.h"
 #include "core/testing/DummyPageHolder.h"
-#include "modules/webaudio/AudioWorkletThread.h"
 #include "platform/testing/TestingPlatformSupport.h"
 #include "platform/wtf/PtrUtil.h"
 #include "public/platform/WebAudioDevice.h"
@@ -94,7 +93,6 @@
   }
 
   void SetUp() override {
-    AudioWorkletThread::CreateSharedBackingThreadForTest();
     dummy_page_holder_ = DummyPageHolder::Create();
   }
 
diff --git a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
index a31945e..63b7772 100644
--- a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
+++ b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
@@ -33,6 +33,7 @@
 #include "platform/WebTaskRunner.h"
 #include "platform/graphics/CanvasHeuristicParameters.h"
 #include "platform/graphics/CanvasMetrics.h"
+#include "platform/graphics/CanvasResource.h"
 #include "platform/graphics/CanvasResourceProvider.h"
 #include "platform/graphics/GraphicsLayer.h"
 #include "platform/graphics/ImageBuffer.h"
@@ -650,12 +651,11 @@
   if (!GetOrCreateResourceProvider())
     return false;
 
-  if (!resource_provider_->IsAccelerated()) {
-  }
-
   FlushRecording();
-  if (resource_provider_->PrepareTransferableResource(out_resource,
-                                                      out_release_callback)) {
+  scoped_refptr<CanvasResource> frame = resource_provider_->ProduceFrame();
+  if (frame) {
+    // Note frame is kept alive via a reference kept in out_release_callback.
+    frame->PrepareTransferableResource(out_resource, out_release_callback);
     out_resource->color_space = color_params_.GetSamplerGfxColorSpace();
     return true;
   }
diff --git a/third_party/WebKit/Source/platform/graphics/CanvasResource.cpp b/third_party/WebKit/Source/platform/graphics/CanvasResource.cpp
index a45436b..ba7e707 100644
--- a/third_party/WebKit/Source/platform/graphics/CanvasResource.cpp
+++ b/third_party/WebKit/Source/platform/graphics/CanvasResource.cpp
@@ -4,8 +4,12 @@
 
 #include "platform/graphics/CanvasResource.h"
 
+#include "components/viz/common/resources/single_release_callback.h"
+#include "components/viz/common/resources/transferable_resource.h"
 #include "gpu/GLES2/gl2extchromium.h"
 #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
+#include "platform/graphics/CanvasResourceProvider.h"
+#include "platform/graphics/gpu/SharedGpuContext.h"
 #include "public/platform/Platform.h"
 #include "skia/ext/texture_handle.h"
 #include "third_party/skia/include/gpu/GrContext.h"
@@ -14,8 +18,12 @@
 namespace blink {
 
 CanvasResource::CanvasResource(
-    base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper)
-    : context_provider_wrapper_(std::move(context_provider_wrapper)) {}
+    base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper,
+    base::WeakPtr<CanvasResourceProvider> provider,
+    SkFilterQuality filter_quality)
+    : context_provider_wrapper_(std::move(context_provider_wrapper)),
+      provider_(std::move(provider)),
+      filter_quality_(filter_quality) {}
 
 CanvasResource::~CanvasResource() {
   // Sync token should have been waited on in sub-class implementation of
@@ -56,22 +64,96 @@
   sync_token_for_release_.Clear();
 }
 
+static void ReleaseFrameResources(
+    base::WeakPtr<CanvasResourceProvider> resource_provider,
+    scoped_refptr<CanvasResource> resource,
+    const gpu::SyncToken& sync_token,
+    bool lost_resource) {
+  resource->SetSyncTokenForRelease(sync_token);
+  if (lost_resource) {
+    resource->Abandon();
+  }
+  if (resource_provider && !lost_resource && resource->IsRecycleable()) {
+    resource_provider->RecycleResource(std::move(resource));
+  }
+}
+
+void CanvasResource::PrepareTransferableResource(
+    viz::TransferableResource* out_resource,
+    std::unique_ptr<viz::SingleReleaseCallback>* out_callback) {
+  // This should never be called on unaccelerated canvases (for now).
+  DCHECK(TextureId());
+
+  // Gpu compositing is a prerequisite for accelerated 2D canvas
+  // TODO: For WebGL to use this, we must add software composing support.
+  DCHECK(SharedGpuContext::IsGpuCompositingEnabled());
+  auto gl = ContextGL();
+  DCHECK(gl);
+
+  GLuint filter =
+      filter_quality_ == kNone_SkFilterQuality ? GL_NEAREST : GL_LINEAR;
+  GLenum target = TextureTarget();
+  GLint texture_id = TextureId();
+
+  gl->BindTexture(target, texture_id);
+  gl->TexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
+  gl->TexParameteri(target, GL_TEXTURE_MIN_FILTER, filter);
+  gl->TexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+  gl->TexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+  gl->ProduceTextureDirectCHROMIUM(texture_id, target, GpuMailbox().name);
+  const GLuint64 fence_sync = gl->InsertFenceSyncCHROMIUM();
+  gl->ShallowFlushCHROMIUM();
+  gpu::SyncToken sync_token;
+  gl->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData());
+
+  *out_resource = viz::TransferableResource::MakeGLOverlay(
+      GpuMailbox(), filter, target, sync_token, gfx::Size(Size()),
+      IsOverlayCandidate());
+
+  gl->BindTexture(target, 0);
+
+  // Because we are changing the texture binding without going through skia,
+  // we must dirty the context.
+  GrContext* gr = GetGrContext();
+  if (gr)
+    gr->resetContext(kTextureBinding_GrGLBackendState);
+
+  scoped_refptr<CanvasResource> this_ref(this);
+  auto func = WTF::Bind(&ReleaseFrameResources, provider_,
+                        WTF::Passed(std::move(this_ref)));
+  *out_callback = viz::SingleReleaseCallback::Create(
+      ConvertToBaseCallback(std::move(func)));
+}
+
+GrContext* CanvasResource::GetGrContext() const {
+  if (!context_provider_wrapper_)
+    return nullptr;
+  return context_provider_wrapper_->ContextProvider()->GetGrContext();
+}
+
 // CanvasResource_Skia
 //==============================================================================
 
 CanvasResource_Skia::CanvasResource_Skia(
     sk_sp<SkImage> image,
-    base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper)
-    : CanvasResource(std::move(context_provider_wrapper)),
+    base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper,
+    base::WeakPtr<CanvasResourceProvider> provider,
+    SkFilterQuality filter_quality)
+    : CanvasResource(std::move(context_provider_wrapper),
+                     std::move(provider),
+                     filter_quality),
       image_(std::move(image)) {}
 
 scoped_refptr<CanvasResource_Skia> CanvasResource_Skia::Create(
     sk_sp<SkImage> image,
-    base::WeakPtr<WebGraphicsContext3DProviderWrapper>
-        context_provider_wrapper) {
+    base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper,
+    base::WeakPtr<CanvasResourceProvider> provider,
+    SkFilterQuality filter_quality) {
   scoped_refptr<CanvasResource_Skia> resource =
       AdoptRef(new CanvasResource_Skia(std::move(image),
-                                       std::move(context_provider_wrapper)));
+                                       std::move(context_provider_wrapper),
+                                       std::move(provider), filter_quality));
   if (resource->IsValid())
     return resource;
   return nullptr;
@@ -98,20 +180,40 @@
   context_provider_wrapper_ = nullptr;
 }
 
+IntSize CanvasResource_Skia::Size() const {
+  return IntSize(image_->width(), image_->height());
+}
+
 GLuint CanvasResource_Skia::TextureId() const {
   DCHECK(image_->isTextureBacked());
   return skia::GrBackendObjectToGrGLTextureInfo(image_->getTextureHandle(true))
       ->fID;
 }
 
+GLenum CanvasResource_Skia::TextureTarget() const {
+  return GL_TEXTURE_2D;
+}
+
+void CanvasResource_Skia::PrepareTransferableResource(
+    viz::TransferableResource* out_resource,
+    std::unique_ptr<viz::SingleReleaseCallback>* out_callback) {
+  DCHECK(image_->isTextureBacked());
+  CanvasResource::PrepareTransferableResource(out_resource, out_callback);
+  image_->getTexture()->textureParamsModified();
+}
+
 // CanvasResource_GpuMemoryBuffer
 //==============================================================================
 
 CanvasResource_GpuMemoryBuffer::CanvasResource_GpuMemoryBuffer(
     const IntSize& size,
     const CanvasColorParams& color_params,
-    base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper)
-    : CanvasResource(std::move(context_provider_wrapper)),
+    base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper,
+    base::WeakPtr<CanvasResourceProvider> provider,
+    SkFilterQuality filter_quality)
+    : CanvasResource(std::move(context_provider_wrapper),
+                     provider,
+                     filter_quality),
       color_params_(color_params) {
   if (!context_provider_wrapper_)
     return;
@@ -150,15 +252,26 @@
   TearDown();
 }
 
+GLenum CanvasResource_GpuMemoryBuffer::TextureTarget() const {
+  return GL_TEXTURE_RECTANGLE_ARB;
+}
+
+IntSize CanvasResource_GpuMemoryBuffer::Size() const {
+  return IntSize(gpu_memory_buffer_->GetSize().width(),
+                 gpu_memory_buffer_->GetSize().height());
+}
+
 scoped_refptr<CanvasResource_GpuMemoryBuffer>
 CanvasResource_GpuMemoryBuffer::Create(
     const IntSize& size,
     const CanvasColorParams& color_params,
-    base::WeakPtr<WebGraphicsContext3DProviderWrapper>
-        context_provider_wrapper) {
+    base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper,
+    base::WeakPtr<CanvasResourceProvider> provider,
+    SkFilterQuality filter_quality) {
   scoped_refptr<CanvasResource_GpuMemoryBuffer> resource =
       AdoptRef(new CanvasResource_GpuMemoryBuffer(size, color_params,
-                                                  context_provider_wrapper));
+                                                  context_provider_wrapper,
+                                                  provider, filter_quality));
   if (resource->IsValid())
     return resource;
   return nullptr;
diff --git a/third_party/WebKit/Source/platform/graphics/CanvasResource.h b/third_party/WebKit/Source/platform/graphics/CanvasResource.h
index 30092d6..3f74902 100644
--- a/third_party/WebKit/Source/platform/graphics/CanvasResource.h
+++ b/third_party/WebKit/Source/platform/graphics/CanvasResource.h
@@ -20,8 +20,17 @@
 
 }  // namespace gfx
 
+namespace viz {
+
+class SingleReleaseCallback;
+struct TransferableResource;
+
+}  // namespace viz
+
 namespace blink {
 
+class CanvasResourceProvider;
+
 // Generic resource interface, used for locking (RAII) and recycling pixel
 // buffers of any type.
 class PLATFORM_EXPORT CanvasResource : public WTF::RefCounted<CanvasResource> {
@@ -31,19 +40,30 @@
   virtual bool IsRecycleable() const = 0;
   virtual bool IsValid() const = 0;
   virtual GLuint TextureId() const = 0;
-  gpu::gles2::GLES2Interface* ContextGL() const;
+  virtual IntSize Size() const = 0;
+  virtual void PrepareTransferableResource(
+      viz::TransferableResource* out_resource,
+      std::unique_ptr<viz::SingleReleaseCallback>* out_callback);
   const gpu::Mailbox& GpuMailbox();
   bool HasGpuMailbox() const;
   void SetSyncTokenForRelease(const gpu::SyncToken&);
   void WaitSyncTokenBeforeRelease();
 
  protected:
-  CanvasResource(base::WeakPtr<WebGraphicsContext3DProviderWrapper>);
+  CanvasResource(base::WeakPtr<WebGraphicsContext3DProviderWrapper>,
+                 base::WeakPtr<CanvasResourceProvider>,
+                 SkFilterQuality);
+  virtual GLenum TextureTarget() const = 0;
+  virtual bool IsOverlayCandidate() const { return false; }
+  gpu::gles2::GLES2Interface* ContextGL() const;
+  GrContext* GetGrContext() const;
 
   gpu::Mailbox gpu_mailbox_;
   // Sync token that was provided when resource was released
   gpu::SyncToken sync_token_for_release_;
   base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper_;
+  base::WeakPtr<CanvasResourceProvider> provider_;
+  SkFilterQuality filter_quality_;
 };
 
 // Resource type for skia Bitmaps (RAM and texture backed)
@@ -51,8 +71,10 @@
  public:
   static scoped_refptr<CanvasResource_Skia> Create(
       sk_sp<SkImage>,
-      base::WeakPtr<WebGraphicsContext3DProviderWrapper>);
-  virtual ~CanvasResource_Skia() { TearDown(); }
+      base::WeakPtr<WebGraphicsContext3DProviderWrapper>,
+      base::WeakPtr<CanvasResourceProvider>,
+      SkFilterQuality);
+  virtual ~CanvasResource_Skia() { Abandon(); }
 
   // Not recyclable: Skia handles texture recycling internally and bitmaps are
   // cheap to allocate.
@@ -60,11 +82,19 @@
   bool IsValid() const final;
   void Abandon() final { TearDown(); }
   GLuint TextureId() const final;
+  IntSize Size() const final;
+  void PrepareTransferableResource(
+      viz::TransferableResource* out_resource,
+      std::unique_ptr<viz::SingleReleaseCallback>* out_callback) final;
 
  private:
   void TearDown();
+  GLenum TextureTarget() const final;
+
   CanvasResource_Skia(sk_sp<SkImage>,
-                      base::WeakPtr<WebGraphicsContext3DProviderWrapper>);
+                      base::WeakPtr<WebGraphicsContext3DProviderWrapper>,
+                      base::WeakPtr<CanvasResourceProvider>,
+                      SkFilterQuality);
 
   sk_sp<SkImage> image_;
 };
@@ -76,19 +106,27 @@
   static scoped_refptr<CanvasResource_GpuMemoryBuffer> Create(
       const IntSize&,
       const CanvasColorParams&,
-      base::WeakPtr<WebGraphicsContext3DProviderWrapper>);
+      base::WeakPtr<WebGraphicsContext3DProviderWrapper>,
+      base::WeakPtr<CanvasResourceProvider>,
+      SkFilterQuality);
   virtual ~CanvasResource_GpuMemoryBuffer();
   bool IsRecycleable() const final { return IsValid(); }
   bool IsValid() const { return context_provider_wrapper_ && image_id_; }
   void Abandon() final { TearDown(); }
   GLuint TextureId() const final { return texture_id_; }
+  IntSize Size() const final;
 
  private:
   void TearDown();
+  GLenum TextureTarget() const final;
+  bool IsOverlayCandidate() const final { return false; }
+
   CanvasResource_GpuMemoryBuffer(
       const IntSize&,
       const CanvasColorParams&,
-      base::WeakPtr<WebGraphicsContext3DProviderWrapper>);
+      base::WeakPtr<WebGraphicsContext3DProviderWrapper>,
+      base::WeakPtr<CanvasResourceProvider>,
+      SkFilterQuality);
 
   std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_;
   GLuint image_id_ = 0;
diff --git a/third_party/WebKit/Source/platform/graphics/CanvasResourceProvider.cpp b/third_party/WebKit/Source/platform/graphics/CanvasResourceProvider.cpp
index de9c7b1..7012ba0a 100644
--- a/third_party/WebKit/Source/platform/graphics/CanvasResourceProvider.cpp
+++ b/third_party/WebKit/Source/platform/graphics/CanvasResourceProvider.cpp
@@ -5,8 +5,6 @@
 #include "platform/graphics/CanvasResourceProvider.h"
 
 #include "cc/paint/skia_paint_canvas.h"
-#include "components/viz/common/resources/single_release_callback.h"
-#include "components/viz/common/resources/transferable_resource.h"
 #include "gpu/GLES2/gl2extchromium.h"
 #include "gpu/command_buffer/common/capabilities.h"
 #include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
@@ -47,48 +45,8 @@
   bool IsValid() const final { return GetSkSurface() && !IsGpuContextLost(); }
   bool IsAccelerated() const final { return true; }
 
-  bool CanPrepareTransferableResource() const final { return true; }
-
  protected:
-  virtual bool isOverlayCandidate() { return false; }
-
-  void TransferResource(CanvasResource* resource,
-                        GLenum target,
-                        viz::TransferableResource* out_resource) {
-    auto gl = ContextGL();
-    auto gr = GetGrContext();
-    DCHECK(gl && gr);
-
-    GLuint texture_id = resource->TextureId();
-    GLuint filter = UseNearestNeighbor() ? GL_NEAREST : GL_LINEAR;
-
-    gl->BindTexture(target, texture_id);
-    gl->TexParameteri(target, GL_TEXTURE_MAG_FILTER, GetGLFilter());
-    gl->TexParameteri(target, GL_TEXTURE_MIN_FILTER, GetGLFilter());
-    gl->TexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    gl->TexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
-    auto mailbox = resource->GpuMailbox();
-    gl->ProduceTextureDirectCHROMIUM(texture_id, target, mailbox.name);
-    const GLuint64 fence_sync = gl->InsertFenceSyncCHROMIUM();
-    gl->ShallowFlushCHROMIUM();
-    gpu::SyncToken sync_token;
-    gl->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData());
-
-    *out_resource = viz::TransferableResource::MakeGLOverlay(
-        mailbox, filter, target, sync_token, gfx::Size(Size()),
-        isOverlayCandidate());
-    out_resource->color_space = ColorParams().GetStorageGfxColorSpace();
-
-    gl->BindTexture(target, 0);
-
-    // Because we are changing the texture binding without going through skia,
-    // we must dirty the context.
-    ResetSkiaTextureBinding();
-  }
-
-  scoped_refptr<CanvasResource> DoPrepareTransferableResource(
-      viz::TransferableResource* out_resource) override {
+  scoped_refptr<CanvasResource> ProduceFrame() override {
     DCHECK(GetSkSurface());
 
     if (IsGpuContextLost())
@@ -110,14 +68,11 @@
       return nullptr;
     DCHECK(image->isTextureBacked());
 
-    scoped_refptr<CanvasResource> resource =
-        CanvasResource_Skia::Create(image, ContextProviderWrapper());
+    scoped_refptr<CanvasResource> resource = CanvasResource_Skia::Create(
+        image, ContextProviderWrapper(), CreateWeakPtr(), FilterQuality());
     if (!resource)
       return nullptr;
 
-    TransferResource(resource.get(), GL_TEXTURE_2D, out_resource);
-    image->getTexture()->textureParamsModified();
-
     return resource;
   }
 
@@ -162,15 +117,13 @@
   virtual ~CanvasResourceProvider_Texture_GpuMemoryBuffer() {}
 
  protected:
-  bool isOverlayCandidate() override { return true; }
-
   scoped_refptr<CanvasResource> CreateResource() final {
-    return CanvasResource_GpuMemoryBuffer::Create(Size(), ColorParams(),
-                                                  ContextProviderWrapper());
+    return CanvasResource_GpuMemoryBuffer::Create(
+        Size(), ColorParams(), ContextProviderWrapper(), CreateWeakPtr(),
+        FilterQuality());
   }
 
-  scoped_refptr<CanvasResource> DoPrepareTransferableResource(
-      viz::TransferableResource* out_resource) final {
+  scoped_refptr<CanvasResource> ProduceFrame() final {
     DCHECK(GetSkSurface());
 
     if (IsGpuContextLost())
@@ -179,8 +132,7 @@
     scoped_refptr<CanvasResource> output_resource = NewOrRecycledResource();
     if (!output_resource) {
       // GpuMemoryBuffer creation failed, fallback to Texture resource
-      return CanvasResourceProvider_Texture::DoPrepareTransferableResource(
-          out_resource);
+      return CanvasResourceProvider_Texture::ProduceFrame();
     }
 
     auto gl = ContextGL();
@@ -205,7 +157,6 @@
                             false /*unpackPremultiplyAlpha*/,
                             false /*unpackUnmultiplyAlpha*/);
 
-    TransferResource(output_resource.get(), target, out_resource);
     return output_resource;
   }
 };
@@ -229,11 +180,8 @@
   bool IsValid() const final { return GetSkSurface(); }
   bool IsAccelerated() const final { return false; }
 
-  bool CanPrepareTransferableResource() const final { return false; }
-
  private:
-  scoped_refptr<CanvasResource> DoPrepareTransferableResource(
-      viz::TransferableResource* out_resource) final {
+  scoped_refptr<CanvasResource> ProduceFrame() final {
     NOTREACHED();  // Not directly compositable.
     return nullptr;
   }
@@ -384,7 +332,7 @@
     // the compositor's behavior. Therefore, we must trigger copy-on-write
     // even though we are not technically writing to the texture, only to its
     // parameters.
-    // If this issue with readback affecting stat is ever fixed, then we'll
+    // If this issue with readback affecting state is ever fixed, then we'll
     // have to do this instead of triggering a copy-on-write:
     // static_cast<AcceleratedStaticBitmapImage*>(image.get())
     //   ->RetainOriginalSkImageForCopyOnWrite();
@@ -410,20 +358,6 @@
   GetSkSurface()->flush();
 }
 
-static void ReleaseFrameResources(
-    base::WeakPtr<CanvasResourceProvider> resource_provider,
-    scoped_refptr<CanvasResource> resource,
-    const gpu::SyncToken& sync_token,
-    bool lost_resource) {
-  resource->SetSyncTokenForRelease(sync_token);
-  if (lost_resource) {
-    resource->Abandon();
-  }
-  if (resource_provider && !lost_resource && resource->IsRecycleable()) {
-    resource_provider->RecycleResource(std::move(resource));
-  }
-}
-
 void CanvasResourceProvider::RecycleResource(
     scoped_refptr<CanvasResource> resource) {
   DCHECK(resource->HasOneRef());
@@ -449,40 +383,11 @@
   return CreateResource();
 }
 
-bool CanvasResourceProvider::PrepareTransferableResource(
-    viz::TransferableResource* out_resource,
-    std::unique_ptr<viz::SingleReleaseCallback>* out_callback) {
-  DCHECK(CanPrepareTransferableResource());
-  scoped_refptr<CanvasResource> resource =
-      DoPrepareTransferableResource(out_resource);
-  if (!resource)
-    return false;
-  auto func = WTF::Bind(&ReleaseFrameResources, weak_ptr_factory_.GetWeakPtr(),
-                        WTF::Passed(std::move(resource)));
-  *out_callback = viz::SingleReleaseCallback::Create(
-      ConvertToBaseCallback(std::move(func)));
-  return true;
-}
-
 bool CanvasResourceProvider::IsGpuContextLost() const {
   auto gl = ContextGL();
   return !gl || gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR;
 }
 
-GLenum CanvasResourceProvider::GetGLFilter() const {
-  return UseNearestNeighbor() ? GL_NEAREST : GL_LINEAR;
-}
-
-bool CanvasResourceProvider::UseNearestNeighbor() const {
-  return filter_quality_ == kNone_SkFilterQuality;
-}
-
-void CanvasResourceProvider::ResetSkiaTextureBinding() const {
-  GrContext* gr = GetGrContext();
-  if (gr)
-    gr->resetContext(kTextureBinding_GrGLBackendState);
-}
-
 void CanvasResourceProvider::ClearRecycledResources() {
   recycled_resources_.clear();
 }
diff --git a/third_party/WebKit/Source/platform/graphics/CanvasResourceProvider.h b/third_party/WebKit/Source/platform/graphics/CanvasResourceProvider.h
index 0ff5a42..13ee4074 100644
--- a/third_party/WebKit/Source/platform/graphics/CanvasResourceProvider.h
+++ b/third_party/WebKit/Source/platform/graphics/CanvasResourceProvider.h
@@ -31,13 +31,6 @@
 }  // namespace gles2
 }  // namespace gpu
 
-namespace viz {
-
-class SingleReleaseCallback;
-struct TransferableResource;
-
-}  // namespace viz
-
 namespace blink {
 
 class CanvasResource;
@@ -77,18 +70,19 @@
       ResourceUsage,
       base::WeakPtr<WebGraphicsContext3DProviderWrapper> = nullptr);
 
+  // Use this method for capturing a frame that is intended to be displayed via
+  // the compositor. Cases that need to acquire a snaptshot that is not destined
+  // to be transfered via TransferableResource should call Snapshot() instead.
+  virtual scoped_refptr<CanvasResource> ProduceFrame() = 0;
+  scoped_refptr<StaticBitmapImage> Snapshot();
+
   cc::PaintCanvas* Canvas();
   void FlushSkia() const;
   const CanvasColorParams& ColorParams() const { return color_params_; }
-  scoped_refptr<StaticBitmapImage> Snapshot();
   void SetFilterQuality(SkFilterQuality quality) { filter_quality_ = quality; }
-  bool PrepareTransferableResource(
-      viz::TransferableResource*,
-      std::unique_ptr<viz::SingleReleaseCallback>*);
   const IntSize& Size() const { return size_; }
   virtual bool IsValid() const = 0;
   virtual bool IsAccelerated() const = 0;
-  virtual bool CanPrepareTransferableResource() const = 0;
   uint32_t ContentUniqueID() const;
   void ClearRecycledResources();
   void RecycleResource(scoped_refptr<CanvasResource>);
@@ -103,10 +97,11 @@
   base::WeakPtr<WebGraphicsContext3DProviderWrapper> ContextProviderWrapper() {
     return context_provider_wrapper_;
   }
-  GLenum GetGLFilter() const;
-  bool UseNearestNeighbor() const;
-  void ResetSkiaTextureBinding() const;
   scoped_refptr<CanvasResource> NewOrRecycledResource();
+  SkFilterQuality FilterQuality() const { return filter_quality_; }
+  base::WeakPtr<CanvasResourceProvider> CreateWeakPtr() {
+    return weak_ptr_factory_.GetWeakPtr();
+  }
 
   // Called by subclasses when the backing resource has changed and resources
   // are not managed by skia, signaling that a new surface needs to be created.
@@ -119,8 +114,6 @@
  private:
   virtual sk_sp<SkSurface> CreateSkSurface() const = 0;
   virtual scoped_refptr<CanvasResource> CreateResource();
-  virtual scoped_refptr<CanvasResource> DoPrepareTransferableResource(
-      viz::TransferableResource* out_resource) = 0;
 
   base::WeakPtrFactory<CanvasResourceProvider> weak_ptr_factory_;
   base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper_;
diff --git a/third_party/WebKit/Source/platform/graphics/CanvasResourceTest.cpp b/third_party/WebKit/Source/platform/graphics/CanvasResourceTest.cpp
index d092f2d..0354ba1 100644
--- a/third_party/WebKit/Source/platform/graphics/CanvasResourceTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/CanvasResourceTest.cpp
@@ -60,7 +60,8 @@
 
   EXPECT_TRUE(!!context_provider_wrapper_);
   scoped_refptr<CanvasResource> resource = CanvasResource_Skia::Create(
-      surface->makeImageSnapshot(), context_provider_wrapper_);
+      surface->makeImageSnapshot(), context_provider_wrapper_, nullptr,
+      kLow_SkFilterQuality);
 
   ::testing::Mock::VerifyAndClearExpectations(&gl_);
 
diff --git a/tools/code_coverage/coverage.py b/tools/code_coverage/coverage.py
index f81a3529..23124cb 100755
--- a/tools/code_coverage/coverage.py
+++ b/tools/code_coverage/coverage.py
@@ -20,10 +20,12 @@
 
   python tools/code_coverage/coverage.py crypto_unittests url_unittests \\
     -b out/coverage -o out/report -c 'out/coverage/crypto_unittests' \\
-    -c 'out/coverage/url_unittests --gtest_filter=URLParser.PathURL'
+    -c 'out/coverage/url_unittests --gtest_filter=URLParser.PathURL' \\
+    -f url/ -f crypto/
 
   The command above generates code coverage report for crypto_unittests and
-  url_unittests and all generated artifacts are stored in out/report.
+  url_unittests with only files under url/ and crypto/ directories are included
+  in the report, and all generated artifacts are stored in out/report.
   For url_unittests, it only runs the test URLParser.PathURL.
 
   If you are building a fuzz target, you need to add "use_libfuzzer=true" GN
@@ -177,7 +179,8 @@
         'Failed to download coverage tools: %s.' % coverage_tools_url)
 
 
-def _GenerateLineByLineFileCoverageInHtml(binary_paths, profdata_file_path):
+def _GenerateLineByLineFileCoverageInHtml(binary_paths, profdata_file_path,
+                                          filters):
   """Generates per file line-by-line coverage in html using 'llvm-cov show'.
 
   For a file with absolute path /a/b/x.cc, a html report is generated as:
@@ -187,6 +190,7 @@
   Args:
     binary_paths: A list of paths to the instrumented binaries.
     profdata_file_path: A path to the profdata file.
+    filters: A list of directories and files to get coverage for.
   """
   print('Generating per file line by line code coverage in html')
 
@@ -201,6 +205,7 @@
   ]
   subprocess_cmd.extend(
       ['-object=' + binary_path for binary_path in binary_paths[1:]])
+  subprocess_cmd.extend(filters)
 
   subprocess.check_call(subprocess_cmd)
 
@@ -443,6 +448,17 @@
   return build_args
 
 
+def _AssertPathsExist(paths):
+  """Asserts that the paths specified in |paths| exist.
+
+  Args:
+    paths: A list of files or directories.
+  """
+  for path in paths:
+    abspath = os.path.join(SRC_ROOT_PATH, path)
+    assert os.path.exists(abspath), ('Path: "%s" doesn\'t exist.' % path)
+
+
 def _ParseCommandArguments():
   """Adds and parses relevant arguments for tool comands.
 
@@ -477,6 +493,14 @@
       'current working directory is the root of the checkout.')
 
   arg_parser.add_argument(
+      '-f',
+      '--filters',
+      action='append',
+      required=True,
+      help='Directories or files to get code coverage for, and all files under '
+      'the directories are included recursively.')
+
+  arg_parser.add_argument(
       '-j',
       '--jobs',
       type=int,
@@ -515,6 +539,9 @@
       'Please run "gn gen" to generate.').format(BUILD_DIR)
   _ValidateBuildingWithClangCoverage()
   _ValidateCommandsAreRelativeToSrcRoot(args.command)
+  if args.filters:
+    _AssertPathsExist(args.filters)
+
   if not os.path.exists(OUTPUT_DIR):
     os.makedirs(OUTPUT_DIR)
 
@@ -522,7 +549,8 @@
       args.targets, args.command, args.jobs)
 
   binary_paths = [_GetBinaryPath(command) for command in args.command]
-  _GenerateLineByLineFileCoverageInHtml(binary_paths, profdata_file_path)
+  _GenerateLineByLineFileCoverageInHtml(binary_paths, profdata_file_path,
+                                        args.filters)
   html_index_file_path = 'file://' + os.path.abspath(
       os.path.join(OUTPUT_DIR, 'index.html'))
   print('\nCode coverage profile data is created as: %s' % profdata_file_path)
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index 1b004cf4..8108a8d 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -1209,6 +1209,13 @@
   </description>
 </action>
 
+<action name="Android.ChromeHome.ClickedSurveyInfoBarCloseButton">
+  <owner>danielpark@chromium.org</owner>
+  <description>
+    User dismissed the survey infobar by tapping on its close button.
+  </description>
+</action>
+
 <action name="Android.ChromeHome.Closed">
   <owner>mdjones@chromium.org</owner>
   <owner>twellington@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 63522dd..4cf6ed1d 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -93859,6 +93859,22 @@
 
 <histogram name="WebApk.Permission.ChromePermissionDenied"
     enum="WebApkPermissionType">
+  <obsolete>
+    Deprecated 2017-11. This UMA logs extra requests. Replaced by
+    ChromePermissionDenied2.
+  </obsolete>
+  <owner>hanxi@chromium.org</owner>
+  <owner>pkotwicz@chromium.org</owner>
+  <owner>ranj@chromium.org</owner>
+  <owner>yfriedman@chromium.org</owner>
+  <summary>
+    The number of Android runtime permission requests that are denied for the
+    WebAPK because Chrome does not have access to that permission.
+  </summary>
+</histogram>
+
+<histogram name="WebApk.Permission.ChromePermissionDenied2"
+    enum="WebApkPermissionType">
   <owner>hanxi@chromium.org</owner>
   <owner>pkotwicz@chromium.org</owner>
   <owner>ranj@chromium.org</owner>
diff --git a/ui/aura/event_injector.cc b/ui/aura/event_injector.cc
index d436128b..ca31c16d 100644
--- a/ui/aura/event_injector.cc
+++ b/ui/aura/event_injector.cc
@@ -45,11 +45,21 @@
 
   if (env->mode() == Env::Mode::LOCAL)
     return host->event_sink()->OnEventFromSource(event);
-  if (!window_server_ptr_) {
-    env->window_tree_client_->connector()->BindInterface(
-        ui::mojom::kServiceName, &window_server_ptr_);
+
+  if (event->IsLocatedEvent()) {
+    // The ui-service expects events coming in to have a location matching the
+    // root location. The non-ui-service code does this by way of
+    // OnEventFromSource() ending up in LocatedEvent::UpdateForRootTransform(),
+    // which reset the root_location to match the location.
+    event->AsLocatedEvent()->set_location_f(
+        event->AsLocatedEvent()->root_location_f());
   }
-  window_server_ptr_->DispatchEvent(
+
+  if (!remote_event_dispatcher_) {
+    env->window_tree_client_->connector()->BindInterface(
+        ui::mojom::kServiceName, &remote_event_dispatcher_);
+  }
+  remote_event_dispatcher_->DispatchEvent(
       host->GetDisplayId(), MapEvent(*event),
       base::Bind([](bool result) { DCHECK(result); }));
   return ui::EventDispatchDetails();
diff --git a/ui/aura/event_injector.h b/ui/aura/event_injector.h
index c43bfc2..acfcf1c 100644
--- a/ui/aura/event_injector.h
+++ b/ui/aura/event_injector.h
@@ -28,7 +28,7 @@
   ui::EventDispatchDetails Inject(WindowTreeHost* host, ui::Event* event);
 
  private:
-  ui::mojom::RemoteEventDispatcherPtr window_server_ptr_;
+  ui::mojom::RemoteEventDispatcherPtr remote_event_dispatcher_;
 
   DISALLOW_COPY_AND_ASSIGN(EventInjector);
 };
diff --git a/ui/webui/resources/cr_elements/chromeos/network/cr_network_list.js b/ui/webui/resources/cr_elements/chromeos/network/cr_network_list.js
index 64e3a13..db81a82 100644
--- a/ui/webui/resources/cr_elements/chromeos/network/cr_network_list.js
+++ b/ui/webui/resources/cr_elements/chromeos/network/cr_network_list.js
@@ -113,9 +113,11 @@
    * @private
    */
   onItemAction_: function(item) {
-    if (item.hasOwnProperty('customItemName'))
+    if (item.hasOwnProperty('customItemName')) {
       this.fire('custom-item-selected', item);
-    else
+    } else {
       this.fire('selected', item);
+      this.focusRequested_ = true;
+    }
   },
 });