diff --git a/.gitignore b/.gitignore
index b17c78e..5e5bebc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -87,7 +87,6 @@
 /chrome/app/theme/default_100_percent/google_chrome
 /chrome/app/theme/default_200_percent/google_chrome
 /chrome/app/theme/google_chrome
-/chrome/browser/autofill/internal
 /chrome/browser/chromeos/arc/voice_interaction/internal
 /chrome/browser/chromeos/assistant/internal
 /chrome/browser/chromeos/login/screenshot_testing/golden_screenshots/*.png
diff --git a/DEPS b/DEPS
index 22f475d..01c3d7b 100644
--- a/DEPS
+++ b/DEPS
@@ -138,11 +138,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '53146121b8ab6c2b80fd244930ebdf6f7b4e7037',
+  'skia_revision': '0cb2fdefc219df122cd764b333fce7e826ab5158',
   # 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': '604b5dab1038614611879011a34e7129ae349767',
+  'v8_revision': 'bcf517c0366d4af6dfb600e5344ef37e65a09d0b',
   # 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.
@@ -150,15 +150,15 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '46fe0e4be950dcbc842e91d50e1468784cc06002',
+  'angle_revision': '5a808b86d8901b9cb7a4d174356c0c1b0e2fc0e3',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
-  'swiftshader_revision': '3971b19ba24228787897efc59e265964b8b5a17f',
+  'swiftshader_revision': '90cb260644cdcdb81e87c6e3bf3ec5885eb23f3b',
   # 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': '7eadbd640fc4c4c3bebfc96110a0c060ea7cc6dd',
+  'pdfium_revision': '12d7da217249af8585e35d0807ee8c3686870714',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
@@ -257,7 +257,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'spv_tools_revision': '78b2b18661fc36330b15e47bf18a5594499b77df',
+  'spv_tools_revision': '5a06fa466186698bcb0757bea201828e47527b98',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -277,7 +277,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'quiche_revision': '034c98c00b23150a20d39e9ce90e71586102bc6c',
+  'quiche_revision': 'e01dd7043f7be26f6860ab3cd4e03273ce98081a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ios_webkit
   # and whatever else without interference from each other.
@@ -477,7 +477,7 @@
   },
 
   'src/ios/third_party/material_components_ios/src': {
-      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'f3f089d8833ef1c33357421779e75054e02c91fa',
+      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '8d01645e5411e1368934b50b7affcb4bba8897ca',
       'condition': 'checkout_ios',
   },
 
@@ -807,7 +807,7 @@
 
   # Build tools for Chrome OS. Note: This depends on third_party/pyelftools.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '6c8f0250717b4859e25f9b72092a6e805c57b7f4',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '162eba28f2077dd9a64e326588b478b2c3cbdf37',
       'condition': 'checkout_linux',
   },
 
@@ -832,7 +832,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '778c7f117aee162dece25d84e00504b2b828655e',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'c5b8a73247c432dbdbc010997f47994e9c3fff43',
 
   'src/third_party/devtools-node-modules':
     Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'),
@@ -1182,7 +1182,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' +  'caa10d3db92bdbc45b6e57d482e632871d300b77',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' +  '21362a5cf0dc76445506fb8e19d50110975c6d2d',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78',
@@ -1350,7 +1350,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '6f0b34abee8dba611c253738d955c59f703c147a',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '07fc398ca8d7ffcd62bb19f9ea1dfcf4959bc700',
+    Var('webrtc_git') + '/src.git' + '@' + 'ce33b6a4cfa06ffa7faec4f33449569d6f319692',
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
@@ -1391,7 +1391,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@0210991491eae8b9e52f5b89048e0e0b35344fda',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@fd40163541b48d82731dad362f4111481bde4e33',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/android_webview/docs/quick-start.md b/android_webview/docs/quick-start.md
index e6ff030..6a5ac503 100644
--- a/android_webview/docs/quick-start.md
+++ b/android_webview/docs/quick-start.md
@@ -134,7 +134,7 @@
 
 *** note
 **Note:** we only support local development using the latest revision of the
-master branch. Checkout out release branches introduces a lot of complexity, and
+master branch. Checking out release branches introduces a lot of complexity, and
 it might not even be possible to build WebView for your device.
 ***
 
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index 70b198f..6c24ecc 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -491,8 +491,6 @@
     "multi_user/user_switch_animator.h",
     "network_connect_delegate_mus.cc",
     "network_connect_delegate_mus.h",
-    "note_taking_controller.cc",
-    "note_taking_controller.h",
     "policy/policy_recommendation_restorer.cc",
     "policy/policy_recommendation_restorer.h",
     "root_window_controller.cc",
@@ -1019,10 +1017,8 @@
     "voice_interaction/voice_interaction_controller.h",
     "wallpaper/wallpaper_base_view.cc",
     "wallpaper/wallpaper_base_view.h",
-    "wallpaper/wallpaper_controller.cc",
-    "wallpaper/wallpaper_controller.h",
-    "wallpaper/wallpaper_controller_observer.h",
-    "wallpaper/wallpaper_info.h",
+    "wallpaper/wallpaper_controller_impl.cc",
+    "wallpaper/wallpaper_controller_impl.h",
     "wallpaper/wallpaper_utils/wallpaper_color_calculator.cc",
     "wallpaper/wallpaper_utils/wallpaper_color_calculator.h",
     "wallpaper/wallpaper_utils/wallpaper_color_calculator_observer.h",
diff --git a/ash/accelerators/debug_commands.cc b/ash/accelerators/debug_commands.cc
index d161a8b..0258861e 100644
--- a/ash/accelerators/debug_commands.cc
+++ b/ash/accelerators/debug_commands.cc
@@ -11,7 +11,7 @@
 #include "ash/system/toast/toast_data.h"
 #include "ash/system/toast/toast_manager.h"
 #include "ash/touch/touch_devices_controller.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
 #include "ash/wm/window_properties.h"
 #include "ash/wm/window_state.h"
@@ -126,8 +126,7 @@
 
 void HandleToggleWallpaperMode() {
   static int index = 0;
-  WallpaperController* wallpaper_controller =
-      Shell::Get()->wallpaper_controller();
+  auto* wallpaper_controller = Shell::Get()->wallpaper_controller();
   WallpaperInfo info("", WALLPAPER_LAYOUT_STRETCH, DEFAULT,
                      base::Time::Now().LocalMidnight());
   switch (++index % 4) {
diff --git a/ash/app_list/OWNERS b/ash/app_list/OWNERS
index 032dcc1..e6adc291 100644
--- a/ash/app_list/OWNERS
+++ b/ash/app_list/OWNERS
@@ -5,3 +5,5 @@
 stevenjb@chromium.org
 weidongg@chromium.org
 xiyuan@chromium.org
+
+# COMPONENT: UI>Shell>Launcher
\ No newline at end of file
diff --git a/ash/app_list/app_list_controller_impl.cc b/ash/app_list/app_list_controller_impl.cc
index 85cfb96..8d54ed8 100644
--- a/ash/app_list/app_list_controller_impl.cc
+++ b/ash/app_list/app_list_controller_impl.cc
@@ -35,7 +35,7 @@
 #include "ash/shelf/shelf_layout_manager.h"
 #include "ash/shell.h"
 #include "ash/voice_interaction/voice_interaction_controller.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "ash/wm/mru_window_tracker.h"
 #include "ash/wm/overview/overview_controller.h"
 #include "ash/wm/splitview/split_view_controller.h"
@@ -1019,9 +1019,9 @@
     client_->StartSearch(base::string16());
 }
 
-void AppListControllerImpl::GetWallpaperProminentColors(
-    GetWallpaperProminentColorsCallback callback) {
-  Shell::Get()->wallpaper_controller()->GetWallpaperColors(std::move(callback));
+const std::vector<SkColor>&
+AppListControllerImpl::GetWallpaperProminentColors() {
+  return Shell::Get()->wallpaper_controller()->GetWallpaperColors();
 }
 
 void AppListControllerImpl::ActivateItem(const std::string& id,
diff --git a/ash/app_list/app_list_controller_impl.h b/ash/app_list/app_list_controller_impl.h
index 430fb47..6d4ed88 100644
--- a/ash/app_list/app_list_controller_impl.h
+++ b/ash/app_list/app_list_controller_impl.h
@@ -25,10 +25,10 @@
 #include "ash/public/cpp/app_list/app_list_controller.h"
 #include "ash/public/cpp/assistant/default_voice_interaction_observer.h"
 #include "ash/public/cpp/shelf_types.h"
+#include "ash/public/cpp/wallpaper_controller_observer.h"
 #include "ash/public/interfaces/voice_interaction_controller.mojom.h"
 #include "ash/session/session_observer.h"
 #include "ash/shell_observer.h"
-#include "ash/wallpaper/wallpaper_controller_observer.h"
 #include "ash/wm/mru_window_tracker.h"
 #include "ash/wm/overview/overview_observer.h"
 #include "ash/wm/tablet_mode/tablet_mode_observer.h"
@@ -176,8 +176,7 @@
   void ViewShown(int64_t display_id) override;
   void ViewClosing() override;
   void ViewClosed() override;
-  void GetWallpaperProminentColors(
-      GetWallpaperProminentColorsCallback callback) override;
+  const std::vector<SkColor>& GetWallpaperProminentColors() override;
   void ActivateItem(const std::string& id,
                     int event_flags,
                     AppListLaunchedFrom launched_from) override;
diff --git a/ash/app_list/app_list_controller_impl_unittest.cc b/ash/app_list/app_list_controller_impl_unittest.cc
index d85e24e4..bef55b2 100644
--- a/ash/app_list/app_list_controller_impl_unittest.cc
+++ b/ash/app_list/app_list_controller_impl_unittest.cc
@@ -17,6 +17,7 @@
 #include "ash/shelf/shelf.h"
 #include "ash/shelf/shelf_widget.h"
 #include "ash/shell.h"
+#include "ash/system/unified/unified_system_tray_test_api.h"
 #include "ash/test/ash_test_base.h"
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
 #include "ash/wm/window_state.h"
@@ -25,6 +26,8 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "ui/events/test/event_generator.h"
+#include "ui/message_center/message_center.h"
+#include "ui/message_center/views/message_popup_view.h"
 
 namespace ash {
 
@@ -247,6 +250,47 @@
             GetAppListViewNativeWindow()->bounds());
 }
 
+// Verifies that closing notification by gesture should not dismiss the AppList.
+// (see https://crbug.com/948344)
+TEST_F(AppListControllerImplTest, CloseNotificationWithAppListShown) {
+  ShowAppListNow();
+
+  // Add one notification.
+  ASSERT_EQ(
+      0u, message_center::MessageCenter::Get()->GetPopupNotifications().size());
+  const std::string notification_id("id");
+  const std::string notification_title("title");
+  message_center::MessageCenter::Get()->AddNotification(
+      std::make_unique<message_center::Notification>(
+          message_center::NOTIFICATION_TYPE_BASE_FORMAT, notification_id,
+          base::UTF8ToUTF16(notification_title),
+          base::UTF8ToUTF16("test message"), gfx::Image(),
+          base::string16() /* display_source */, GURL(),
+          message_center::NotifierId(), message_center::RichNotificationData(),
+          new message_center::NotificationDelegate()));
+  base::RunLoop().RunUntilIdle();
+  ASSERT_EQ(
+      1u, message_center::MessageCenter::Get()->GetPopupNotifications().size());
+
+  // Calculate the drag start point and end point.
+  UnifiedSystemTrayTestApi test_api(GetPrimaryUnifiedSystemTray());
+  message_center::MessagePopupView* popup_view =
+      test_api.GetPopupViewForNotificationID(notification_id);
+  ASSERT_TRUE(popup_view);
+  gfx::Rect bounds_in_screen = popup_view->GetBoundsInScreen();
+  const gfx::Point drag_start = bounds_in_screen.left_center();
+  const gfx::Point drag_end = bounds_in_screen.right_center();
+
+  // Swipe away notification by gesture. Verifies that AppListView still shows.
+  ui::test::EventGenerator* event_generator = GetEventGenerator();
+  event_generator->GestureScrollSequence(
+      drag_start, drag_end, base::TimeDelta::FromMicroseconds(500), 10);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_TRUE(GetAppListView());
+  EXPECT_EQ(
+      0u, message_center::MessageCenter::Get()->GetPopupNotifications().size());
+}
+
 class AppListControllerImplMetricsTest : public AshTestBase {
  public:
   AppListControllerImplMetricsTest() = default;
diff --git a/ash/app_list/app_list_view_delegate.h b/ash/app_list/app_list_view_delegate.h
index 64542f4e..e59ed53 100644
--- a/ash/app_list/app_list_view_delegate.h
+++ b/ash/app_list/app_list_view_delegate.h
@@ -110,10 +110,7 @@
   virtual void ViewClosed() = 0;
 
   // Gets the wallpaper prominent colors.
-  using GetWallpaperProminentColorsCallback =
-      base::OnceCallback<void(const std::vector<SkColor>&)>;
-  virtual void GetWallpaperProminentColors(
-      GetWallpaperProminentColorsCallback callback) = 0;
+  virtual const std::vector<SkColor>& GetWallpaperProminentColors() = 0;
 
   // Activates (opens) the item.
   virtual void ActivateItem(const std::string& id,
diff --git a/ash/app_list/test/app_list_test_view_delegate.cc b/ash/app_list/test/app_list_test_view_delegate.cc
index af1a553..958d5fe 100644
--- a/ash/app_list/test/app_list_test_view_delegate.cc
+++ b/ash/app_list/test/app_list_test_view_delegate.cc
@@ -83,6 +83,11 @@
   search_model_->SetSearchEngineIsGoogle(is_google);
 }
 
+const std::vector<SkColor>&
+AppListTestViewDelegate::GetWallpaperProminentColors() {
+  return wallpaper_prominent_colors_;
+}
+
 void AppListTestViewDelegate::ActivateItem(
     const std::string& id,
     int event_flags,
diff --git a/ash/app_list/test/app_list_test_view_delegate.h b/ash/app_list/test/app_list_test_view_delegate.h
index 7919d45..9eb472f0 100644
--- a/ash/app_list/test/app_list_test_view_delegate.h
+++ b/ash/app_list/test/app_list_test_view_delegate.h
@@ -80,8 +80,7 @@
   void DismissAppList() override;
   void ViewClosing() override {}
   void ViewClosed() override {}
-  void GetWallpaperProminentColors(
-      GetWallpaperProminentColorsCallback callback) override {}
+  const std::vector<SkColor>& GetWallpaperProminentColors() override;
   void ActivateItem(const std::string& id,
                     int event_flags,
                     ash::AppListLaunchedFrom launched_from) override;
diff --git a/ash/app_list/views/app_list_view.cc b/ash/app_list/views/app_list_view.cc
index 4174ff0..6eaa211 100644
--- a/ash/app_list/views/app_list_view.cc
+++ b/ash/app_list/views/app_list_view.cc
@@ -23,7 +23,6 @@
 #include "ash/public/cpp/ash_features.h"
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/public/cpp/wallpaper_types.h"
-#include "base/bind.h"
 #include "base/macros.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/metrics/user_metrics.h"
@@ -131,21 +130,20 @@
   DISALLOW_COPY_AND_ASSIGN(SearchBoxFocusHost);
 };
 
-SkColor GetBackgroundShieldColor(const std::vector<SkColor>& prominent_colors,
+SkColor GetBackgroundShieldColor(const std::vector<SkColor>& colors,
                                  float color_opacity) {
   const U8CPU sk_opacity_value = static_cast<U8CPU>(255 * color_opacity);
 
   const SkColor default_color = SkColorSetA(
       app_list::AppListView::kDefaultBackgroundColor, sk_opacity_value);
 
-  if (prominent_colors.empty())
+  if (colors.empty())
     return default_color;
 
   DCHECK_EQ(static_cast<size_t>(ColorProfileType::NUM_OF_COLOR_PROFILES),
-            prominent_colors.size());
-
+            colors.size());
   const SkColor dark_muted =
-      prominent_colors[static_cast<int>(ColorProfileType::DARK_MUTED)];
+      colors[static_cast<int>(ColorProfileType::DARK_MUTED)];
   if (SK_ColorTRANSPARENT == dark_muted)
     return default_color;
 
@@ -1991,11 +1989,6 @@
   return coefficient * shield_opacity + (1 - coefficient) * shelf_opacity;
 }
 
-void AppListView::GetWallpaperProminentColors(
-    AppListViewDelegate::GetWallpaperProminentColorsCallback callback) {
-  delegate_->GetWallpaperProminentColors(std::move(callback));
-}
-
 void AppListView::SetBackgroundShieldColor() {
   // There is a chance when AppListView::OnWallpaperColorsChanged is called
   // from AppListViewDelegate, the |app_list_background_shield_| is not
@@ -2018,13 +2011,8 @@
     color_opacity = kAppListOpacityWithBlur;
   }
 
-  GetWallpaperProminentColors(base::BindOnce(
-      [](base::WeakPtr<AppListView> self, float color_opacity,
-         const std::vector<SkColor>& prominent_colors) {
-        self->app_list_background_shield_->UpdateColor(
-            GetBackgroundShieldColor(prominent_colors, color_opacity));
-      },
-      weak_ptr_factory_.GetWeakPtr(), color_opacity));
+  app_list_background_shield_->UpdateColor(GetBackgroundShieldColor(
+      delegate_->GetWallpaperProminentColors(), color_opacity));
 }
 
 void AppListView::RecordFolderMetrics() {
diff --git a/ash/app_list/views/app_list_view.h b/ash/app_list/views/app_list_view.h
index 133d1c3..3e6d166 100644
--- a/ash/app_list/views/app_list_view.h
+++ b/ash/app_list/views/app_list_view.h
@@ -411,8 +411,7 @@
   // Gets app list background opacity during dragging.
   float GetAppListBackgroundOpacityDuringDragging();
 
-  void GetWallpaperProminentColors(
-      AppListViewDelegate::GetWallpaperProminentColorsCallback callback);
+  const std::vector<SkColor>& GetWallpaperProminentColors();
   void SetBackgroundShieldColor();
 
   // Records the number of folders, and the number of items in folders for UMA
diff --git a/ash/app_list/views/search_box_view.cc b/ash/app_list/views/search_box_view.cc
index bd53841a..379a2b3 100644
--- a/ash/app_list/views/search_box_view.cc
+++ b/ash/app_list/views/search_box_view.cc
@@ -396,9 +396,18 @@
 }
 
 void SearchBoxView::OnWallpaperColorsChanged() {
-  GetWallpaperProminentColors(
-      base::BindOnce(&SearchBoxView::OnWallpaperProminentColorsReceived,
-                     weak_ptr_factory_.GetWeakPtr()));
+  const auto& colors = view_delegate_->GetWallpaperProminentColors();
+  if (colors.empty())
+    return;
+
+  DCHECK_EQ(static_cast<size_t>(ColorProfileType::NUM_OF_COLOR_PROFILES),
+            colors.size());
+
+  SetSearchBoxColor(colors[static_cast<int>(ColorProfileType::DARK_MUTED)]);
+  UpdateSearchIcon();
+  search_box()->set_placeholder_text_color(search_box_color());
+  UpdateBackgroundColor(search_box::kSearchBoxBackgroundDefault);
+  SchedulePaint();
 }
 
 void SearchBoxView::ProcessAutocomplete() {
@@ -439,26 +448,6 @@
   ClearAutocompleteText();
 }
 
-void SearchBoxView::GetWallpaperProminentColors(
-    AppListViewDelegate::GetWallpaperProminentColorsCallback callback) {
-  view_delegate_->GetWallpaperProminentColors(std::move(callback));
-}
-
-void SearchBoxView::OnWallpaperProminentColorsReceived(
-    const std::vector<SkColor>& prominent_colors) {
-  if (prominent_colors.empty())
-    return;
-  DCHECK_EQ(static_cast<size_t>(ColorProfileType::NUM_OF_COLOR_PROFILES),
-            prominent_colors.size());
-
-  SetSearchBoxColor(
-      prominent_colors[static_cast<int>(ColorProfileType::DARK_MUTED)]);
-  UpdateSearchIcon();
-  search_box()->set_placeholder_text_color(search_box_color());
-  UpdateBackgroundColor(search_box::kSearchBoxBackgroundDefault);
-  SchedulePaint();
-}
-
 void SearchBoxView::AcceptAutocompleteText() {
   if (!ShouldProcessAutocomplete())
     return;
diff --git a/ash/app_list/views/search_box_view.h b/ash/app_list/views/search_box_view.h
index 5198637..2af523e 100644
--- a/ash/app_list/views/search_box_view.h
+++ b/ash/app_list/views/search_box_view.h
@@ -109,15 +109,6 @@
   }
 
  private:
-  // Gets the wallpaper prominent colors.
-  void GetWallpaperProminentColors(
-      AppListViewDelegate::GetWallpaperProminentColorsCallback callback);
-
-  // Callback invoked when the wallpaper prominent colors are returned after
-  // calling |AppListViewDelegate::GetWallpaperProminentColors|.
-  void OnWallpaperProminentColorsReceived(
-      const std::vector<SkColor>& prominent_colors);
-
   // Notifies SearchBoxViewDelegate that the autocomplete text is valid.
   void AcceptAutocompleteText();
 
diff --git a/ash/ash_prefs.cc b/ash/ash_prefs.cc
index 5f55958..ade78c0e 100644
--- a/ash/ash_prefs.cc
+++ b/ash/ash_prefs.cc
@@ -23,7 +23,7 @@
 #include "ash/system/power/power_prefs.h"
 #include "ash/system/session/logout_button_tray.h"
 #include "ash/touch/touch_devices_controller.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 
 namespace ash {
 
@@ -53,7 +53,7 @@
 
 void RegisterLocalStatePrefs(PrefRegistrySimple* registry, bool for_test) {
   PaletteTray::RegisterLocalStatePrefs(registry);
-  WallpaperController::RegisterLocalStatePrefs(registry);
+  WallpaperControllerImpl::RegisterLocalStatePrefs(registry);
   BluetoothPowerController::RegisterLocalStatePrefs(registry);
   DetachableBaseHandler::RegisterPrefs(registry);
   PowerPrefs::RegisterLocalStatePrefs(registry);
diff --git a/ash/home_screen/home_screen_controller.cc b/ash/home_screen/home_screen_controller.cc
index e436114..77d46ea6 100644
--- a/ash/home_screen/home_screen_controller.cc
+++ b/ash/home_screen/home_screen_controller.cc
@@ -10,7 +10,7 @@
 #include "ash/session/session_controller_impl.h"
 #include "ash/shelf/shelf.h"
 #include "ash/shell.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "ash/wm/mru_window_tracker.h"
 #include "ash/wm/overview/overview_controller.h"
 #include "ash/wm/overview/overview_session.h"
diff --git a/ash/home_screen/home_screen_controller.h b/ash/home_screen/home_screen_controller.h
index ca51256..fb6469b 100644
--- a/ash/home_screen/home_screen_controller.h
+++ b/ash/home_screen/home_screen_controller.h
@@ -9,7 +9,7 @@
 
 #include "ash/ash_export.h"
 #include "ash/home_screen/home_screen_presenter.h"
-#include "ash/wallpaper/wallpaper_controller_observer.h"
+#include "ash/public/cpp/wallpaper_controller_observer.h"
 #include "ash/wm/overview/overview_observer.h"
 #include "base/macros.h"
 
diff --git a/ash/login/login_screen_controller_unittest.cc b/ash/login/login_screen_controller_unittest.cc
index abac013..d4c93af 100644
--- a/ash/login/login_screen_controller_unittest.cc
+++ b/ash/login/login_screen_controller_unittest.cc
@@ -15,7 +15,7 @@
 #include "ash/system/tray/system_tray_notifier.h"
 #include "ash/system/unified/unified_system_tray.h"
 #include "ash/test/ash_test_base.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "base/bind.h"
 #include "base/run_loop.h"
 #include "base/test/bind_test_util.h"
diff --git a/ash/login/ui/lock_debug_view.cc b/ash/login/ui/lock_debug_view.cc
index 80392727..b24f61f 100644
--- a/ash/login/ui/lock_debug_view.cc
+++ b/ash/login/ui/lock_debug_view.cc
@@ -24,7 +24,7 @@
 #include "ash/shelf/shelf.h"
 #include "ash/shelf/shelf_widget.h"
 #include "ash/shell.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "base/bind.h"
 #include "base/memory/ptr_util.h"
 #include "base/optional.h"
diff --git a/ash/login/ui/lock_screen.cc b/ash/login/ui/lock_screen.cc
index 4bf83d4..7eedb40 100644
--- a/ash/login/ui/lock_screen.cc
+++ b/ash/login/ui/lock_screen.cc
@@ -18,7 +18,7 @@
 #include "ash/shelf/shelf_widget.h"
 #include "ash/shell.h"
 #include "ash/tray_action/tray_action.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "chromeos/constants/chromeos_switches.h"
diff --git a/ash/login/ui/login_auth_user_view.cc b/ash/login/ui/login_auth_user_view.cc
index 72f2388..93e6284c 100644
--- a/ash/login/ui/login_auth_user_view.cc
+++ b/ash/login/ui/login_auth_user_view.cc
@@ -24,7 +24,7 @@
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/system/night_light/time_of_day.h"
 #include "ash/system/toast/toast_manager.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "base/bind.h"
 #include "base/i18n/time_formatting.h"
 #include "base/strings/utf_string_conversions.h"
diff --git a/ash/login/ui/login_big_user_view.cc b/ash/login/ui/login_big_user_view.cc
index 80afdbf2..c1e4a105 100644
--- a/ash/login/ui/login_big_user_view.cc
+++ b/ash/login/ui/login_big_user_view.cc
@@ -5,7 +5,7 @@
 #include "ash/login/ui/login_big_user_view.h"
 #include "ash/public/cpp/login_constants.h"
 #include "ash/shell.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "components/account_id/account_id.h"
 #include "ui/views/background.h"
 #include "ui/views/layout/fill_layout.h"
diff --git a/ash/login/ui/login_big_user_view.h b/ash/login/ui/login_big_user_view.h
index 4ac774fb..daeda31 100644
--- a/ash/login/ui/login_big_user_view.h
+++ b/ash/login/ui/login_big_user_view.h
@@ -12,7 +12,7 @@
 #include "ash/login/ui/non_accessible_view.h"
 #include "ash/login/ui/parent_access_view.h"
 #include "ash/public/cpp/session/user_info.h"
-#include "ash/wallpaper/wallpaper_controller_observer.h"
+#include "ash/public/cpp/wallpaper_controller_observer.h"
 
 namespace ash {
 
diff --git a/ash/login/ui/login_keyboard_test_base.cc b/ash/login/ui/login_keyboard_test_base.cc
index f4f87cc..c4cd4bcb 100644
--- a/ash/login/ui/login_keyboard_test_base.cc
+++ b/ash/login/ui/login_keyboard_test_base.cc
@@ -15,7 +15,6 @@
 #include "ash/root_window_controller.h"
 #include "ash/session/test_session_controller_client.h"
 #include "ash/shell.h"
-#include "ash/wallpaper/wallpaper_controller.h"
 #include "base/command_line.h"
 #include "base/strings/strcat.h"
 
diff --git a/ash/login/ui/login_test_base.cc b/ash/login/ui/login_test_base.cc
index ab14fc2..86c34440 100644
--- a/ash/login/ui/login_test_base.cc
+++ b/ash/login/ui/login_test_base.cc
@@ -13,7 +13,7 @@
 #include "ash/public/interfaces/tray_action.mojom.h"
 #include "ash/session/test_session_controller_client.h"
 #include "ash/shell.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "base/bind.h"
 #include "base/strings/strcat.h"
 #include "ui/views/widget/widget.h"
diff --git a/ash/login/ui/parent_access_view.cc b/ash/login/ui/parent_access_view.cc
index af1d35b..61ef1676 100644
--- a/ash/login/ui/parent_access_view.cc
+++ b/ash/login/ui/parent_access_view.cc
@@ -15,7 +15,7 @@
 #include "ash/resources/vector_icons/vector_icons.h"
 #include "ash/shell.h"
 #include "ash/strings/grit/ash_strings.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/optional.h"
diff --git a/ash/login/ui/scrollable_users_list_view.cc b/ash/login/ui/scrollable_users_list_view.cc
index 76b2a02..a7fddacf 100644
--- a/ash/login/ui/scrollable_users_list_view.cc
+++ b/ash/login/ui/scrollable_users_list_view.cc
@@ -13,7 +13,7 @@
 #include "ash/login/ui/views_utils.h"
 #include "ash/public/cpp/login_constants.h"
 #include "ash/shell.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "base/bind.h"
 #include "base/numerics/ranges.h"
 #include "base/timer/timer.h"
@@ -387,7 +387,7 @@
 
   // Only draw a gradient if the wallpaper is blurred. Otherwise, draw a rounded
   // rectangle.
-  if (ash::Shell::Get()->wallpaper_controller()->IsWallpaperBlurred()) {
+  if (Shell::Get()->wallpaper_controller()->IsWallpaperBlurred()) {
     cc::PaintFlags flags;
 
     // Only draw a gradient if the content can be scrolled.
diff --git a/ash/login/ui/scrollable_users_list_view.h b/ash/login/ui/scrollable_users_list_view.h
index 5e0e9e0..6a4637f5 100644
--- a/ash/login/ui/scrollable_users_list_view.h
+++ b/ash/login/ui/scrollable_users_list_view.h
@@ -10,7 +10,7 @@
 #include "ash/ash_export.h"
 #include "ash/login/ui/login_display_style.h"
 #include "ash/login/ui/login_user_view.h"
-#include "ash/wallpaper/wallpaper_controller_observer.h"
+#include "ash/public/cpp/wallpaper_controller_observer.h"
 #include "base/scoped_observer.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/views/controls/scroll_view.h"
@@ -97,8 +97,7 @@
 
   GradientParams gradient_params_;
 
-  ScopedObserver<WallpaperController, WallpaperControllerObserver> observer_{
-      this};
+  ScopedObserver<WallpaperController, ScrollableUsersListView> observer_{this};
 
   DISALLOW_COPY_AND_ASSIGN(ScrollableUsersListView);
 };
diff --git a/ash/mojo_interface_factory.cc b/ash/mojo_interface_factory.cc
index fe37770..ffde7009 100644
--- a/ash/mojo_interface_factory.cc
+++ b/ash/mojo_interface_factory.cc
@@ -24,7 +24,6 @@
 #include "ash/kiosk_next/kiosk_next_shell_controller.h"
 #include "ash/login/login_screen_controller.h"
 #include "ash/media/media_controller.h"
-#include "ash/note_taking_controller.h"
 #include "ash/public/cpp/ash_features.h"
 #include "ash/public/cpp/ash_switches.h"
 #include "ash/shell.h"
@@ -36,7 +35,6 @@
 #include "ash/system/night_light/night_light_controller.h"
 #include "ash/tray_action/tray_action.h"
 #include "ash/voice_interaction/voice_interaction_controller.h"
-#include "ash/wallpaper/wallpaper_controller.h"
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
 #include "base/bind.h"
 #include "base/command_line.h"
@@ -151,11 +149,6 @@
   Shell::Get()->night_light_controller()->BindRequest(std::move(request));
 }
 
-void BindNoteTakingControllerRequestOnMainThread(
-    mojom::NoteTakingControllerRequest request) {
-  Shell::Get()->note_taking_controller()->BindRequest(std::move(request));
-}
-
 void BindShelfIntegrationTestApiRequestOnMainThread(
     mojom::ShelfIntegrationTestApiRequest request) {
   ShelfIntegrationTestApi::BindRequest(std::move(request));
@@ -184,11 +177,6 @@
   Shell::Get()->vpn_list()->BindRequest(std::move(request));
 }
 
-void BindWallpaperRequestOnMainThread(
-    mojom::WallpaperControllerRequest request) {
-  Shell::Get()->wallpaper_controller()->BindRequest(std::move(request));
-}
-
 }  // namespace
 
 void RegisterInterfaces(
@@ -260,9 +248,6 @@
       base::BindRepeating(&BindNightLightControllerRequestOnMainThread),
       main_thread_task_runner);
   registry->AddInterface(
-      base::BindRepeating(&BindNoteTakingControllerRequestOnMainThread),
-      main_thread_task_runner);
-  registry->AddInterface(
       base::BindRepeating(&BindShutdownControllerRequestOnMainThread),
       main_thread_task_runner);
   registry->AddInterface(
@@ -276,8 +261,6 @@
       main_thread_task_runner);
   registry->AddInterface(base::BindRepeating(&BindVpnListRequestOnMainThread),
                          main_thread_task_runner);
-  registry->AddInterface(base::BindRepeating(&BindWallpaperRequestOnMainThread),
-                         main_thread_task_runner);
 
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kAshEnableTestInterfaces)) {
diff --git a/ash/multi_user/multi_user_window_manager_impl.cc b/ash/multi_user/multi_user_window_manager_impl.cc
index bdea8799..22188ba 100644
--- a/ash/multi_user/multi_user_window_manager_impl.cc
+++ b/ash/multi_user/multi_user_window_manager_impl.cc
@@ -12,6 +12,7 @@
 #include "ash/public/cpp/multi_user_window_manager_delegate.h"
 #include "ash/public/cpp/multi_user_window_manager_observer.h"
 #include "ash/public/cpp/shell_window_ids.h"
+#include "ash/public/cpp/wallpaper_user_info.h"
 #include "ash/session/session_controller_impl.h"
 #include "ash/shell.h"
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
@@ -58,20 +59,18 @@
   return false;
 }
 
-mojom::WallpaperUserInfoPtr WallpaperUserInfoForAccount(
-    const AccountId& account_id) {
+WallpaperUserInfo WallpaperUserInfoForAccount(const AccountId& account_id) {
   DCHECK(account_id.is_valid());
-  mojom::WallpaperUserInfoPtr wallpaper_user_info =
-      mojom::WallpaperUserInfo::New();
+  WallpaperUserInfo wallpaper_user_info;
   SessionControllerImpl* session_controller =
       Shell::Get()->session_controller();
   for (const std::unique_ptr<UserSession>& user_session :
        session_controller->GetUserSessions()) {
     if (user_session->user_info.account_id == account_id) {
-      wallpaper_user_info->account_id = account_id;
-      wallpaper_user_info->type = user_session->user_info.type;
-      wallpaper_user_info->is_ephemeral = user_session->user_info.is_ephemeral;
-      wallpaper_user_info->has_gaia_account =
+      wallpaper_user_info.account_id = account_id;
+      wallpaper_user_info.type = user_session->user_info.type;
+      wallpaper_user_info.is_ephemeral = user_session->user_info.is_ephemeral;
+      wallpaper_user_info.has_gaia_account =
           user_session->user_info.has_gaia_account;
       return wallpaper_user_info;
     }
diff --git a/ash/multi_user/user_switch_animator.cc b/ash/multi_user/user_switch_animator.cc
index 7abe9c4b..78eabc79 100644
--- a/ash/multi_user/user_switch_animator.cc
+++ b/ash/multi_user/user_switch_animator.cc
@@ -7,7 +7,7 @@
 #include "ash/multi_user/multi_user_window_manager_impl.h"
 #include "ash/public/cpp/multi_user_window_manager_delegate.h"
 #include "ash/shell.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "ash/wm/mru_window_tracker.h"
 #include "ash/wm/window_positioner.h"
 #include "base/bind.h"
@@ -82,11 +82,11 @@
 
 UserSwitchAnimator::UserSwitchAnimator(
     MultiUserWindowManagerImpl* owner,
-    mojom::WallpaperUserInfoPtr wallpaper_user_info,
+    const WallpaperUserInfo& wallpaper_user_info,
     base::TimeDelta animation_speed)
     : owner_(owner),
-      wallpaper_user_info_(std::move(wallpaper_user_info)),
-      new_account_id_(wallpaper_user_info_->account_id),
+      wallpaper_user_info_(wallpaper_user_info),
+      new_account_id_(wallpaper_user_info_.account_id),
       animation_speed_(animation_speed),
       animation_step_(ANIMATION_STEP_HIDE_OLD_USER),
       screen_cover_(GetScreenCover(NULL)),
@@ -160,8 +160,7 @@
 }
 
 void UserSwitchAnimator::TransitionWallpaper(AnimationStep animation_step) {
-  WallpaperController* wallpaper_controller =
-      Shell::Get()->wallpaper_controller();
+  auto* wallpaper_controller = Shell::Get()->wallpaper_controller();
 
   // Handle the wallpaper switch.
   if (animation_step == ANIMATION_STEP_HIDE_OLD_USER) {
@@ -172,8 +171,7 @@
     wallpaper_controller->SetAnimationDuration(
         duration > kMinimalAnimationTime ? duration : kMinimalAnimationTime);
     if (screen_cover_ != NEW_USER_COVERS_SCREEN) {
-      DCHECK(wallpaper_user_info_);
-      wallpaper_controller->ShowUserWallpaper(std::move(wallpaper_user_info_));
+      wallpaper_controller->ShowUserWallpaper(wallpaper_user_info_);
       wallpaper_user_id_for_test_ =
           (NO_USER_COVERS_SCREEN == screen_cover_ ? "->" : "") +
           new_account_id_.Serialize();
@@ -181,10 +179,8 @@
   } else if (animation_step == ANIMATION_STEP_FINALIZE) {
     // Revert the wallpaper cross dissolve animation duration back to the
     // default.
-    if (screen_cover_ == NEW_USER_COVERS_SCREEN) {
-      DCHECK(wallpaper_user_info_);
-      wallpaper_controller->ShowUserWallpaper(std::move(wallpaper_user_info_));
-    }
+    if (screen_cover_ == NEW_USER_COVERS_SCREEN)
+      wallpaper_controller->ShowUserWallpaper(wallpaper_user_info_);
 
     // Coming here the wallpaper user id is the final result. No matter how we
     // got here.
diff --git a/ash/multi_user/user_switch_animator.h b/ash/multi_user/user_switch_animator.h
index 78978e6..79a2414 100644
--- a/ash/multi_user/user_switch_animator.h
+++ b/ash/multi_user/user_switch_animator.h
@@ -10,7 +10,7 @@
 #include <string>
 
 #include "ash/ash_export.h"
-#include "ash/public/interfaces/wallpaper.mojom.h"
+#include "ash/public/cpp/wallpaper_user_info.h"
 #include "base/macros.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
@@ -39,7 +39,7 @@
   // Creates a UserSwitchAnimator to animate between the current user and
   // |user_info|.
   UserSwitchAnimator(MultiUserWindowManagerImpl* owner,
-                     mojom::WallpaperUserInfoPtr user_info,
+                     const WallpaperUserInfo& user_info,
                      base::TimeDelta animation_speed);
   ~UserSwitchAnimator();
 
@@ -103,7 +103,7 @@
 
   // Contains the wallpaper configuration for the user switching to. This is
   // passed to the WallpaperController at the right time.
-  mojom::WallpaperUserInfoPtr wallpaper_user_info_;
+  WallpaperUserInfo wallpaper_user_info_;
 
   // The new user to set.
   AccountId new_account_id_;
diff --git a/ash/note_taking_controller.cc b/ash/note_taking_controller.cc
deleted file mode 100644
index b7f5066..0000000
--- a/ash/note_taking_controller.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// 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 "ash/note_taking_controller.h"
-#include "base/bind.h"
-
-namespace ash {
-
-NoteTakingController::NoteTakingController() : binding_(this) {}
-
-NoteTakingController::~NoteTakingController() = default;
-
-void NoteTakingController::BindRequest(
-    mojom::NoteTakingControllerRequest request) {
-  binding_.Bind(std::move(request));
-}
-
-void NoteTakingController::SetClient(
-    mojom::NoteTakingControllerClientPtr client) {
-  DCHECK(!client_);
-  client_ = std::move(client);
-  client_.set_connection_error_handler(base::Bind(
-      &NoteTakingController::OnClientConnectionLost, base::Unretained(this)));
-}
-
-bool NoteTakingController::CanCreateNote() const {
-  return static_cast<bool>(client_);
-}
-
-void NoteTakingController::CreateNote() {
-  DCHECK(client_);
-  client_->CreateNote();
-}
-
-void NoteTakingController::OnClientConnectionLost() {
-  client_.reset();
-  binding_.Close();
-}
-
-void NoteTakingController::FlushMojoForTesting() {
-  if (client_)
-    client_.FlushForTesting();
-}
-
-}  // namespace ash
diff --git a/ash/note_taking_controller.h b/ash/note_taking_controller.h
deleted file mode 100644
index 97ccd9b..0000000
--- a/ash/note_taking_controller.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// 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.
-
-#ifndef ASH_NOTETAKING_CONTROLLER_H_
-#define ASH_NOTETAKING_CONTROLLER_H_
-
-#include "ash/ash_export.h"
-#include "ash/public/interfaces/note_taking_controller.mojom.h"
-#include "mojo/public/cpp/bindings/binding.h"
-
-namespace ash {
-
-// Controller for the note taking functionality.
-class ASH_EXPORT NoteTakingController : public mojom::NoteTakingController {
- public:
-  NoteTakingController();
-  ~NoteTakingController() override;
-
-  void BindRequest(mojom::NoteTakingControllerRequest request);
-
-  // mojom::NoteTakingController:
-  void SetClient(mojom::NoteTakingControllerClientPtr client) override;
-
-  // Returns true if the client is attached.
-  bool CanCreateNote() const;
-
-  // Calls the method of the same name on |client_|.
-  void CreateNote();
-
- private:
-  friend class TestNoteTakingControllerClient;
-
-  void OnClientConnectionLost();
-
-  void FlushMojoForTesting();
-
-  // Binding for mojom::NoteTakingController interface.
-  mojo::Binding<ash::mojom::NoteTakingController> binding_;
-
-  // Interface to NoteTaking controller client (chrome).
-  mojom::NoteTakingControllerClientPtr client_;
-
-  DISALLOW_COPY_AND_ASSIGN(NoteTakingController);
-};
-
-}  // namespace ash
-
-#endif  // ASH_NOTETAKING_CONTROLLER_H_
diff --git a/ash/public/cpp/BUILD.gn b/ash/public/cpp/BUILD.gn
index e12ddb5..4247ccdb7 100644
--- a/ash/public/cpp/BUILD.gn
+++ b/ash/public/cpp/BUILD.gn
@@ -99,6 +99,8 @@
     "network_icon_image_source.h",
     "new_window_delegate.cc",
     "new_window_delegate.h",
+    "note_taking_client.cc",
+    "note_taking_client.h",
     "notification_utils.cc",
     "notification_utils.h",
     "pagination/pagination_controller.cc",
@@ -147,7 +149,14 @@
     "tablet_mode.h",
     "touch_uma.cc",
     "touch_uma.h",
+    "wallpaper_controller.cc",
+    "wallpaper_controller.h",
+    "wallpaper_controller_client.h",
+    "wallpaper_controller_observer.cc",
+    "wallpaper_controller_observer.h",
+    "wallpaper_info.h",
     "wallpaper_types.h",
+    "wallpaper_user_info.h",
     "window_animation_types.h",
     "window_properties.cc",
     "window_properties.h",
@@ -183,6 +192,7 @@
     "//ash/public/interfaces:interfaces_internal",
     "//base",
     "//components/session_manager:base",
+    "//components/user_manager",
     "//ui/gfx",
   ]
 
diff --git a/ash/public/cpp/app_list/OWNERS b/ash/public/cpp/app_list/OWNERS
index 730511a..6467b609 100644
--- a/ash/public/cpp/app_list/OWNERS
+++ b/ash/public/cpp/app_list/OWNERS
@@ -2,3 +2,5 @@
 
 per-file *_struct_traits*.*=set noparent
 per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
+
+# COMPONENT: UI>Shell>Launcher
\ No newline at end of file
diff --git a/ash/public/cpp/manifest.cc b/ash/public/cpp/manifest.cc
index b4ffcb94..8859baa 100644
--- a/ash/public/cpp/manifest.cc
+++ b/ash/public/cpp/manifest.cc
@@ -20,14 +20,12 @@
 #include "ash/public/interfaces/login_screen.mojom.h"
 #include "ash/public/interfaces/media.mojom.h"
 #include "ash/public/interfaces/night_light_controller.mojom.h"
-#include "ash/public/interfaces/note_taking_controller.mojom.h"
 #include "ash/public/interfaces/shelf_integration_test_api.mojom.h"
 #include "ash/public/interfaces/shutdown.mojom.h"
 #include "ash/public/interfaces/tablet_mode.mojom.h"
 #include "ash/public/interfaces/tray_action.mojom.h"
 #include "ash/public/interfaces/voice_interaction_controller.mojom.h"
 #include "ash/public/interfaces/vpn_list.mojom.h"
-#include "ash/public/interfaces/wallpaper.mojom.h"
 #include "base/no_destructor.h"
 #include "chromeos/services/multidevice_setup/public/mojom/constants.mojom.h"
 #include "chromeos/services/network_config/public/mojom/constants.mojom.h"
@@ -74,10 +72,9 @@
                   mojom::ImeController, mojom::KeyboardController,
                   mojom::LocaleUpdateController, mojom::LoginScreen,
                   mojom::MediaController, mojom::NightLightController,
-                  mojom::NoteTakingController, mojom::ShutdownController,
-                  mojom::TabletModeController, mojom::TrayAction,
-                  mojom::VoiceInteractionController, mojom::VpnList,
-                  mojom::WallpaperController>())
+                  mojom::ShutdownController, mojom::TabletModeController,
+                  mojom::TrayAction, mojom::VoiceInteractionController,
+                  mojom::VpnList>())
           .ExposeCapability("test", service_manager::Manifest::InterfaceList<
                                         mojom::ShelfIntegrationTestApi>())
           .RequireCapability("*", "accessibility")
diff --git a/ash/public/cpp/note_taking_client.cc b/ash/public/cpp/note_taking_client.cc
new file mode 100644
index 0000000..0bb88295
--- /dev/null
+++ b/ash/public/cpp/note_taking_client.cc
@@ -0,0 +1,29 @@
+// Copyright 2019 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 "ash/public/cpp/note_taking_client.h"
+
+#include "base/logging.h"
+
+namespace ash {
+namespace {
+NoteTakingClient* g_note_taking_client = nullptr;
+}
+
+// static
+NoteTakingClient* NoteTakingClient::GetInstance() {
+  return g_note_taking_client;
+}
+
+NoteTakingClient::NoteTakingClient() {
+  DCHECK(!g_note_taking_client);
+  g_note_taking_client = this;
+}
+
+NoteTakingClient::~NoteTakingClient() {
+  DCHECK_EQ(g_note_taking_client, this);
+  g_note_taking_client = nullptr;
+}
+
+}  // namespace ash
diff --git a/ash/public/cpp/note_taking_client.h b/ash/public/cpp/note_taking_client.h
new file mode 100644
index 0000000..ce22ba3
--- /dev/null
+++ b/ash/public/cpp/note_taking_client.h
@@ -0,0 +1,35 @@
+// Copyright 2019 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.
+
+#ifndef ASH_PUBLIC_CPP_NOTE_TAKING_CLIENT_H_
+#define ASH_PUBLIC_CPP_NOTE_TAKING_CLIENT_H_
+
+#include "ash/public/cpp/ash_public_export.h"
+#include "base/macros.h"
+
+namespace ash {
+
+// Interface for ash to notify the client (e.g. Chrome) about the new note
+// creation.
+class ASH_PUBLIC_EXPORT NoteTakingClient {
+ public:
+  static NoteTakingClient* GetInstance();
+
+  // Returns true when it can create notes.
+  virtual bool CanCreateNote() = 0;
+
+  // Called when the controller needs to create a new note.
+  virtual void CreateNote() = 0;
+
+ protected:
+  NoteTakingClient();
+  virtual ~NoteTakingClient();
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(NoteTakingClient);
+};
+
+}  // namespace ash
+
+#endif  // ASH_PUBLIC_CPP_NOTE_TAKING_CLIENT_H_
diff --git a/ash/public/cpp/vector_icons/notification_end_of_support.icon b/ash/public/cpp/vector_icons/notification_end_of_support.icon
index 475ccda..29d8ae6 100644
--- a/ash/public/cpp/vector_icons/notification_end_of_support.icon
+++ b/ash/public/cpp/vector_icons/notification_end_of_support.icon
@@ -3,41 +3,27 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 96,
-MOVE_TO, 71.34f, 15.46f,
-R_CUBIC_TO, 3.55f, 2.54f, 6.65f, 5.65f, 9.2f, 9.2f,
-R_CUBIC_TO, 4.68f, 6.52f, 7.46f, 14.5f, 7.46f, 23.14f,
-CUBIC_TO, 88, 56.44f, 85.22f, 64.42f, 80.49f, 71,
-LINE_TO, 62, 53,
-R_H_LINE_TO, 6,
-LINE_TO, 48.2f, 27.9f,
-R_LINE_TO, -4.8f, 6.01f,
-CUBIC_TO_SHORTHAND, 25.04f, 15.48f, 25.06f, 15.46f,
-CUBIC_TO, 31.59f, 10.79f, 39.56f, 8, 48.2f, 8,
-R_CUBIC_TO, 8.64f, 0, 16.61f, 2.79f, 23.14f, 7.46f,
+MOVE_TO, 44, 68,
+LINE_TO, 52, 68,
+LINE_TO, 52, 44,
+LINE_TO, 44, 44,
 CLOSE,
-R_MOVE_TO, 9.51f, 64.84f,
-LINE_TO, 84, 83.44f,
-LINE_TO, 79.44f, 88,
-R_LINE_TO, -7.81f, -7.7f,
-R_CUBIC_TO, -6.57f, 4.72f, -14.61f, 7.52f, -23.31f, 7.52f,
-R_CUBIC_TO, -8.71f, 0, -16.74f, -2.8f, -23.31f, -7.52f,
-R_CUBIC_TO, -3.57f, -2.56f, -6.7f, -5.69f, -9.27f, -9.26f,
-R_CUBIC_TO, -4.71f, -6.57f, -7.52f, -14.61f, -7.52f, -23.31f,
-R_CUBIC_TO, 0, -8.71f, 2.8f, -16.74f, 7.52f, -23.42f,
-LINE_TO, 8, 16.56f,
-LINE_TO, 12.56f, 12,
-R_LINE_TO, 3.18f, 3.18f,
-R_LINE_TO, 4.21f, 4.21f,
-LINE_TO, 39.39f, 38.83f,
-R_LINE_TO, 18.95f, 18.87f,
-LINE_TO, 76.69f, 76.05f,
-R_LINE_TO, 4.17f, 4.25f,
+MOVE_TO, 48, 8,
+CUBIC_TO, 25.9f, 8, 8, 25.9f, 8, 48,
+CUBIC_TO, 8, 70.1f, 25.9f, 88, 48, 88,
+CUBIC_TO, 70.1f, 88, 88, 70.1f, 88, 48,
+CUBIC_TO, 88, 25.9f, 70.1f, 8, 48, 8,
 CLOSE,
-MOVE_TO, 57, 68,
-R_V_LINE_TO, -1.33f,
-LINE_TO, 34.91f, 44,
-LINE_TO, 28, 53,
-R_H_LINE_TO, 9,
-R_V_LINE_TO, 15,
-R_H_LINE_TO, 20,
-CLOSE
+MOVE_TO, 48, 80,
+CUBIC_TO, 30.36f, 80, 16, 65.64f, 16, 48,
+CUBIC_TO, 16, 30.36f, 30.36f, 16, 48, 16,
+CUBIC_TO, 65.64f, 16, 80, 30.36f, 80, 48,
+CUBIC_TO, 80, 65.64f, 65.64f, 80, 48, 80,
+CLOSE,
+MOVE_TO, 44, 36,
+LINE_TO, 52, 36,
+LINE_TO, 52, 28,
+LINE_TO, 44, 28,
+CLOSE,
+MOVE_TO, 44, 36,
+CLOSE
\ No newline at end of file
diff --git a/ash/public/cpp/wallpaper_controller.cc b/ash/public/cpp/wallpaper_controller.cc
new file mode 100644
index 0000000..17eaa8b
--- /dev/null
+++ b/ash/public/cpp/wallpaper_controller.cc
@@ -0,0 +1,17 @@
+// Copyright 2019 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 "ash/public/cpp/wallpaper_controller.h"
+
+namespace ash {
+
+// static
+WallpaperController* WallpaperController::Get() {
+  return g_instance_;
+}
+
+// static
+WallpaperController* WallpaperController::g_instance_ = nullptr;
+
+}  // namespace ash
diff --git a/ash/public/cpp/wallpaper_controller.h b/ash/public/cpp/wallpaper_controller.h
new file mode 100644
index 0000000..d570a36
--- /dev/null
+++ b/ash/public/cpp/wallpaper_controller.h
@@ -0,0 +1,278 @@
+// Copyright 2019 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.
+
+#ifndef ASH_PUBLIC_CPP_WALLPAPER_CONTROLLER_H_
+#define ASH_PUBLIC_CPP_WALLPAPER_CONTROLLER_H_
+
+#include <string>
+#include <vector>
+
+#include "ash/public/cpp/ash_public_export.h"
+#include "ash/public/cpp/wallpaper_info.h"
+#include "ash/public/cpp/wallpaper_types.h"
+#include "base/files/file_path.h"
+#include "base/time/time.h"
+
+namespace gfx {
+class ImageSkia;
+}
+
+namespace ash {
+
+class WallpaperControllerObserver;
+class WallpaperControllerClient;
+struct WallpaperUserInfo;
+
+// Used by Chrome to set the wallpaper displayed by ash.
+class ASH_PUBLIC_EXPORT WallpaperController {
+ public:
+  static WallpaperController* Get();
+
+  // Do the initialization: Sets the client interface, the paths of wallpaper
+  // directories and the device wallpaper policy enforcement flag. The paths
+  // must be sent over IPC because chrome owns the concept of user data
+  // directory.
+  // |client|: The client interface.
+  // |user_data_path|: Directory where user data can be written.
+  // |chromeos_wallpapers_path|: Directory where downloaded chromeos wallpapers
+  //                             reside.
+  // |chromeos_custom_wallpapers_path|: Directory where custom wallpapers
+  //                                    reside.
+  // |device_policy_wallpaper_path|: The file path of the device policy
+  //                                 wallpaper (if any).
+  virtual void Init(WallpaperControllerClient* client,
+                    const base::FilePath& user_data_path,
+                    const base::FilePath& chromeos_wallpapers_path,
+                    const base::FilePath& chromeos_custom_wallpapers_path,
+                    const base::FilePath& device_policy_wallpaper_path) = 0;
+
+  // Sets wallpaper from a local file and updates the saved wallpaper info for
+  // the user.
+  // |user_info|: The user's information related to wallpaper.
+  // |wallpaper_files_id|: The file id for user_info.account_id.
+  // |file_name|: The name of the wallpaper file.
+  // |layout|: The layout of the wallpaper, used for wallpaper resizing.
+  // |image|: The wallpaper image.
+  // |preview_mode|: If true, show the wallpaper immediately but doesn't change
+  //                 the user wallpaper info until |ConfirmPreviewWallpaper| is
+  //                 called.
+  virtual void SetCustomWallpaper(const WallpaperUserInfo& user_info,
+                                  const std::string& wallpaper_files_id,
+                                  const std::string& file_name,
+                                  WallpaperLayout layout,
+                                  const gfx::ImageSkia& image,
+                                  bool preview_mode) = 0;
+
+  // Sets wallpaper from the Chrome OS wallpaper picker. If the wallpaper file
+  // corresponding to |url| already exists in local file system (i.e.
+  // |SetOnlineWallpaperFromData| was called earlier with the same |url|),
+  // returns true and sets wallpaper for the user, otherwise returns false.
+  // |user_info|: The user's information related to wallpaper.
+  // |url|: The wallpaper url.
+  // |layout|: The layout of the wallpaper, used for wallpaper resizing.
+  // |preview_mode|: If true, show the wallpaper immediately but doesn't change
+  //                 the user wallpaper info until |ConfirmPreviewWallpaper| is
+  //                 called.
+  // Responds with true if the wallpaper file exists in local file system.
+  using SetOnlineWallpaperIfExistsCallback = base::OnceCallback<void(bool)>;
+  virtual void SetOnlineWallpaperIfExists(
+      const WallpaperUserInfo& user_info,
+      const std::string& url,
+      WallpaperLayout layout,
+      bool preview_mode,
+      SetOnlineWallpaperIfExistsCallback callback) = 0;
+
+  // Sets wallpaper from the Chrome OS wallpaper picker and saves the wallpaper
+  // to local file system. After this, |SetOnlineWallpaperIfExists| will return
+  // true for the same |url|, so that there's no need to provide |image_data|
+  // when the same wallpaper needs to be set again or for another user.
+  // |user_info|: The user's information related to wallpaper.
+  // |url|: The wallpaper url.
+  // |layout|: The layout of the wallpaper, used for wallpaper resizing.
+  // |preview_mode|: If true, show the wallpaper immediately but doesn't change
+  //                 the user wallpaper info until |ConfirmPreviewWallpaper| is
+  //                 called.
+  // Responds with true if the wallpaper is set successfully (i.e. no decoding
+  // error etc.).
+  using SetOnlineWallpaperFromDataCallback = base::OnceCallback<void(bool)>;
+  virtual void SetOnlineWallpaperFromData(
+      const WallpaperUserInfo& user_info,
+      const std::string& image_data,
+      const std::string& url,
+      WallpaperLayout layout,
+      bool preview_mode,
+      SetOnlineWallpaperFromDataCallback callback) = 0;
+
+  // Sets the user's wallpaper to be the default wallpaper. Note: different user
+  // types may have different default wallpapers.
+  // |wallpaper_files_id|: The file id for user_info.account_id.
+  // |show_wallpaper|: If false, don't show the new wallpaper now but only
+  //                   update cache.
+  virtual void SetDefaultWallpaper(const WallpaperUserInfo& user_info,
+                                   const std::string& wallpaper_files_id,
+                                   bool show_wallpaper) = 0;
+
+  // Sets the paths of the customized default wallpaper to be used wherever a
+  // default wallpaper is needed. If a default wallpaper is being shown, updates
+  // the screen to replace the old default wallpaper. Note: it doesn't change
+  // the default wallpaper for guest and child accounts.
+  // |customized_default_small_path|: The file path of the small-size customized
+  //                                  default wallpaper, if any.
+  // |customized_default_large_path|: The file path of the large-size customized
+  //                                  default wallpaper, if any.
+  virtual void SetCustomizedDefaultWallpaperPaths(
+      const base::FilePath& customized_default_small_path,
+      const base::FilePath& customized_default_large_path) = 0;
+
+  // Sets wallpaper from policy. If the user has logged in, show the policy
+  // wallpaper immediately, otherwise, the policy wallpaper will be shown the
+  // next time |ShowUserWallpaper| is called. Note: it is different from device
+  // policy.
+  // |user_info|: The user's information related to wallpaper.
+  // |wallpaper_files_id|: The file id for user_info.account_id.
+  // |data|: The data used to decode the image.
+  virtual void SetPolicyWallpaper(const WallpaperUserInfo& user_info,
+                                  const std::string& wallpaper_files_id,
+                                  const std::string& data) = 0;
+
+  // Sets the path of device policy wallpaper.
+  // |device_policy_wallpaper_path|: The file path of the device policy
+  //                                 wallpaper if it was set or empty value if
+  //                                 it was cleared.
+  virtual void SetDevicePolicyWallpaperPath(
+      const base::FilePath& device_policy_wallpaper_path) = 0;
+
+  // Sets wallpaper from a third-party app (as opposed to the Chrome OS
+  // wallpaper picker).
+  // |user_info|: The user's information related to wallpaper.
+  // |wallpaper_files_id|: The file id for user_info.account_id.
+  // |file_name|: The name of the wallpaper file.
+  // |layout|: The layout of the wallpaper, used for wallpaper resizing.
+  // |image|: The wallpaper image.
+  // Returns if the wallpaper is allowed to be shown on screen. It's false if:
+  // 1) the user is not permitted to change wallpaper, or
+  // 2) updating the on-screen wallpaper is not allowed at the given moment.
+  virtual bool SetThirdPartyWallpaper(const WallpaperUserInfo& user_info,
+                                      const std::string& wallpaper_files_id,
+                                      const std::string& file_name,
+                                      WallpaperLayout layout,
+                                      const gfx::ImageSkia& image) = 0;
+
+  // Confirms the wallpaper being previewed to be set as the actual user
+  // wallpaper. Must be called in preview mode.
+  virtual void ConfirmPreviewWallpaper() = 0;
+
+  // Cancels the wallpaper preview and reverts to the user wallpaper. Must be
+  // called in preview mode.
+  virtual void CancelPreviewWallpaper() = 0;
+
+  // Updates the layout for the user's custom wallpaper and reloads the
+  // wallpaper with the new layout.
+  // |user_info|: The user's information related to wallpaper.
+  // |layout|: The new layout of the wallpaper.
+  virtual void UpdateCustomWallpaperLayout(const WallpaperUserInfo& user_info,
+                                           WallpaperLayout layout) = 0;
+
+  // Shows the user's wallpaper, which is determined in the following order:
+  // 1) Use device policy wallpaper if it exists AND we are at the login screen.
+  // 2) Use user policy wallpaper if it exists.
+  // 3) Use the wallpaper set by the user (either by |SetOnlineWallpaper| or
+  //    |SetCustomWallpaper|), if any.
+  // 4) Use the default wallpaper of this user.
+  virtual void ShowUserWallpaper(const WallpaperUserInfo& user_info) = 0;
+
+  // Used by the gaia-signin UI. Signin wallpaper is considered either as the
+  // device policy wallpaper or the default wallpaper.
+  virtual void ShowSigninWallpaper() = 0;
+
+  // Shows a one-shot wallpaper, which does not belong to any particular user
+  // and is not saved to file. Note: the wallpaper will never be dimmed or
+  // blurred because it's assumed that the caller wants to show the image as is
+  // when using this method.
+  virtual void ShowOneShotWallpaper(const gfx::ImageSkia& image) = 0;
+
+  // Shows a wallpaper that stays on top of everything except for the power off
+  // animation. All other wallpaper requests are ignored when the always-on-top
+  // wallpaper is being shown.
+  // |image_path|: The file path to read the image data from.
+  virtual void ShowAlwaysOnTopWallpaper(const base::FilePath& image_path) = 0;
+
+  // Removes the always-on-top wallpaper. The wallpaper will revert to the
+  // previous one, or a default one if there was none. No-op if the current
+  // wallpaper is not always-on-top.
+  virtual void RemoveAlwaysOnTopWallpaper() = 0;
+
+  // Removes all of the user's saved wallpapers and related info.
+  // |wallpaper_files_id|: The file id for user_info.account_id.
+  virtual void RemoveUserWallpaper(const WallpaperUserInfo& user_info,
+                                   const std::string& wallpaper_files_id) = 0;
+
+  // Removes all of the user's saved wallpapers and related info if the
+  // wallpaper was set by |SetPolicyWallpaper|. In addition, sets the user's
+  // wallpaper to be the default. If the user has logged in, show the default
+  // wallpaper immediately, otherwise, the default wallpaper will be shown the
+  // next time |ShowUserWallpaper| is called.
+  // |user_info|: The user's information related to wallpaper.
+  // |wallpaper_files_id|: The file id for user_info.account_id.
+  virtual void RemovePolicyWallpaper(const WallpaperUserInfo& user_info,
+                                     const std::string& wallpaper_files_id) = 0;
+
+  // Returns the urls of the wallpapers that exist in local file system (i.e.
+  // |SetOnlineWallpaperFromData| was called earlier). The url is used as id
+  // to identify which wallpapers are available to be set offline.
+  using GetOfflineWallpaperListCallback =
+      base::OnceCallback<void(const std::vector<std::string>&)>;
+  virtual void GetOfflineWallpaperList(
+      GetOfflineWallpaperListCallback callback) = 0;
+
+  // Sets wallpaper animation duration. Passing an empty value disables the
+  // animation.
+  virtual void SetAnimationDuration(base::TimeDelta animation_duration) = 0;
+
+  // Opens the wallpaper picker if the active user is not controlled by policy
+  // and it's allowed to change wallpaper per the user type and the login state.
+  virtual void OpenWallpaperPickerIfAllowed() = 0;
+
+  // Minimizes all windows except the active window.
+  // |user_id_hash|: The hash value corresponding to |User::username_hash|.
+  virtual void MinimizeInactiveWindows(const std::string& user_id_hash) = 0;
+
+  // Restores all minimized windows to their previous states. This should only
+  // be called after calling |MinimizeInactiveWindows|.
+  // |user_id_hash|: The hash value corresponding to |User::username_hash|.
+  virtual void RestoreMinimizedWindows(const std::string& user_id_hash) = 0;
+
+  // Add and remove wallpaper observers.
+  virtual void AddObserver(WallpaperControllerObserver* observer) = 0;
+  virtual void RemoveObserver(WallpaperControllerObserver* observer) = 0;
+
+  // Returns the wallpaper image currently being shown.
+  virtual gfx::ImageSkia GetWallpaperImage() = 0;
+
+  // Returns the wallpaper prominent colors.
+  virtual const std::vector<SkColor>& GetWallpaperColors() = 0;
+
+  // Returns whether the current wallpaper is blurred.
+  virtual bool IsWallpaperBlurred() = 0;
+
+  // Returns true if the wallpaper of the currently active user (if any) is
+  // controlled by policy (excluding device policy). If there's no active user,
+  // returns false.
+  virtual bool IsActiveUserWallpaperControlledByPolicy() = 0;
+
+  // Returns a struct with info about the active user's wallpaper; the location
+  // is an empty string and the layout is invalid if there's no active user.
+  virtual WallpaperInfo GetActiveUserWallpaperInfo() = 0;
+
+  // Returns true if the wallpaper setting (used to open the wallpaper picker)
+  // should be visible.
+  virtual bool ShouldShowWallpaperSetting() = 0;
+
+ protected:
+  static WallpaperController* g_instance_;
+};
+
+}  // namespace ash
+
+#endif  // ASH_PUBLIC_CPP_WALLPAPER_CONTROLLER_H_
diff --git a/ash/public/cpp/wallpaper_controller_client.h b/ash/public/cpp/wallpaper_controller_client.h
new file mode 100644
index 0000000..8556241
--- /dev/null
+++ b/ash/public/cpp/wallpaper_controller_client.h
@@ -0,0 +1,31 @@
+// Copyright 2019 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.
+
+#ifndef ASH_PUBLIC_CPP_WALLPAPER_CONTROLLER_CLIENT_H_
+#define ASH_PUBLIC_CPP_WALLPAPER_CONTROLLER_CLIENT_H_
+
+#include "ash/public/cpp/ash_public_export.h"
+
+namespace ash {
+
+// Used by ash to control a Chrome client of the WallpaperController.
+class ASH_PUBLIC_EXPORT WallpaperControllerClient {
+ public:
+  // Opens the wallpaper picker window.
+  virtual void OpenWallpaperPicker() = 0;
+
+  // Signals to the client that ash is ready to set wallpapers. The client is
+  // able to decide whatever the first wallpaper it wants to display.
+  virtual void OnReadyToSetWallpaper() = 0;
+
+  // Notifies the client that the animation of the first wallpaper since the
+  // controller initialization has completed.
+  // TODO(crbug.com/875128): Remove this after web-ui login code is completely
+  // removed.
+  virtual void OnFirstWallpaperAnimationFinished() = 0;
+};
+
+}  // namespace ash
+
+#endif  // ASH_PUBLIC_CPP_WALLPAPER_CONTROLLER_CLIENT_H_
diff --git a/ash/public/cpp/wallpaper_controller_observer.cc b/ash/public/cpp/wallpaper_controller_observer.cc
new file mode 100644
index 0000000..3fc933e
--- /dev/null
+++ b/ash/public/cpp/wallpaper_controller_observer.cc
@@ -0,0 +1,13 @@
+// Copyright 2019 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 "ash/public/cpp/wallpaper_controller_observer.h"
+
+namespace ash {
+
+WallpaperControllerObserver::WallpaperControllerObserver() = default;
+
+WallpaperControllerObserver::~WallpaperControllerObserver() = default;
+
+}  // namespace ash
diff --git a/ash/public/cpp/wallpaper_controller_observer.h b/ash/public/cpp/wallpaper_controller_observer.h
new file mode 100644
index 0000000..6d58154
--- /dev/null
+++ b/ash/public/cpp/wallpaper_controller_observer.h
@@ -0,0 +1,48 @@
+// Copyright 2019 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.
+
+#ifndef ASH_PUBLIC_CPP_WALLPAPER_CONTROLLER_OBSERVER_H_
+#define ASH_PUBLIC_CPP_WALLPAPER_CONTROLLER_OBSERVER_H_
+
+#include "ash/public/cpp/ash_public_export.h"
+#include "base/macros.h"
+
+namespace ash {
+
+// Used to listen for wallpaper state changes.
+class ASH_PUBLIC_EXPORT WallpaperControllerObserver {
+ public:
+  WallpaperControllerObserver();
+
+  // Invoked when the wallpaper is changed.
+  virtual void OnWallpaperChanged() {}
+
+  // Invoked when the colors extracted from the current wallpaper change.
+  virtual void OnWallpaperColorsChanged() {}
+
+  // Invoked when the blur state of the wallpaper changes.
+  // TODO(crbug.com/875128): Remove this after web-ui login code is completely
+  // removed.
+  virtual void OnWallpaperBlurChanged() {}
+
+  // Invoked when the wallpaper preview mode starts.
+  virtual void OnWallpaperPreviewStarted() {}
+
+  // Invoked when the wallpaper preview mode ends.
+  virtual void OnWallpaperPreviewEnded() {}
+
+  // Invoked when the first wallpaper is set. The first wallpaper is the one
+  // shown right after boot splash screen or after a session restart.
+  virtual void OnFirstWallpaperShown() {}
+
+ protected:
+  virtual ~WallpaperControllerObserver();
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(WallpaperControllerObserver);
+};
+
+}  // namespace ash
+
+#endif  // ASH_PUBLIC_CPP_WALLPAPER_CONTROLLER_OBSERVER_H_
diff --git a/ash/wallpaper/wallpaper_info.h b/ash/public/cpp/wallpaper_info.h
similarity index 89%
rename from ash/wallpaper/wallpaper_info.h
rename to ash/public/cpp/wallpaper_info.h
index 671f32c3..c88ddf4 100644
--- a/ash/wallpaper/wallpaper_info.h
+++ b/ash/public/cpp/wallpaper_info.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 ASH_WALLPAPER_WALLPAPER_INFO_H_
-#define ASH_WALLPAPER_WALLPAPER_INFO_H_
+#ifndef ASH_PUBLIC_CPP_WALLPAPER_INFO_H_
+#define ASH_PUBLIC_CPP_WALLPAPER_INFO_H_
 
 #include "ash/public/cpp/wallpaper_types.h"
 #include "base/time/time.h"
@@ -40,4 +40,4 @@
 
 }  // namespace ash
 
-#endif  // ASH_WALLPAPER_WALLPAPER_INFO_H_
+#endif  // ASH_PUBLIC_CPP_WALLPAPER_INFO_H_
diff --git a/ash/public/cpp/wallpaper_struct_traits.h b/ash/public/cpp/wallpaper_struct_traits.h
deleted file mode 100644
index 590eed9..0000000
--- a/ash/public/cpp/wallpaper_struct_traits.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// 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.
-
-#ifndef ASH_PUBLIC_CPP_WALLPAPER_STRUCT_TRAITS_H_
-#define ASH_PUBLIC_CPP_WALLPAPER_STRUCT_TRAITS_H_
-
-#include "ash/public/cpp/wallpaper_types.h"
-#include "ash/public/interfaces/wallpaper.mojom.h"
-
-namespace mojo {
-
-template <>
-struct EnumTraits<ash::mojom::WallpaperLayout, ash::WallpaperLayout> {
-  static ash::mojom::WallpaperLayout ToMojom(ash::WallpaperLayout input) {
-    switch (input) {
-      case ash::WALLPAPER_LAYOUT_CENTER:
-        return ash::mojom::WallpaperLayout::CENTER;
-      case ash::WALLPAPER_LAYOUT_CENTER_CROPPED:
-        return ash::mojom::WallpaperLayout::CENTER_CROPPED;
-      case ash::WALLPAPER_LAYOUT_STRETCH:
-        return ash::mojom::WallpaperLayout::STRETCH;
-      case ash::WALLPAPER_LAYOUT_TILE:
-        return ash::mojom::WallpaperLayout::TILE;
-      case ash::NUM_WALLPAPER_LAYOUT:
-        break;
-    }
-    NOTREACHED();
-    return ash::mojom::WallpaperLayout::CENTER;
-  }
-
-  static bool FromMojom(ash::mojom::WallpaperLayout input,
-                        ash::WallpaperLayout* out) {
-    switch (input) {
-      case ash::mojom::WallpaperLayout::CENTER:
-        *out = ash::WALLPAPER_LAYOUT_CENTER;
-        return true;
-      case ash::mojom::WallpaperLayout::CENTER_CROPPED:
-        *out = ash::WALLPAPER_LAYOUT_CENTER_CROPPED;
-        return true;
-      case ash::mojom::WallpaperLayout::STRETCH:
-        *out = ash::WALLPAPER_LAYOUT_STRETCH;
-        return true;
-      case ash::mojom::WallpaperLayout::TILE:
-        *out = ash::WALLPAPER_LAYOUT_TILE;
-        return true;
-    }
-    NOTREACHED();
-    return false;
-  }
-};
-
-}  // namespace mojo
-
-#endif  // ASH_PUBLIC_CPP_WALLPAPER_STRUCT_TRAITS_H_
diff --git a/ash/public/cpp/wallpaper_user_info.h b/ash/public/cpp/wallpaper_user_info.h
new file mode 100644
index 0000000..254d4964
--- /dev/null
+++ b/ash/public/cpp/wallpaper_user_info.h
@@ -0,0 +1,36 @@
+// Copyright 2019 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.
+
+#ifndef ASH_PUBLIC_CPP_WALLPAPER_USER_INFO_H_
+#define ASH_PUBLIC_CPP_WALLPAPER_USER_INFO_H_
+
+#include "ash/public/cpp/ash_public_export.h"
+#include "components/account_id/account_id.h"
+#include "components/user_manager/user_type.h"
+
+namespace ash {
+
+// User info needed to set wallpapers. Clients must specify the user because
+// it's not always the same as the active user, e.g., when showing wallpapers
+// for different user pods at login screen, or setting wallpapers selectively
+// for primary user and active user during a multi-profile session.
+struct ASH_PUBLIC_EXPORT WallpaperUserInfo {
+  // The user's account id.
+  AccountId account_id = EmptyAccountId();
+
+  // The user type.
+  user_manager::UserType type = user_manager::USER_TYPE_REGULAR;
+
+  // True if the user's non-cryptohome data (wallpaper, avatar etc.) is
+  // ephemeral. See |UserManager::IsCurrentUserNonCryptohomeDataEphemeral| for
+  // more details.
+  bool is_ephemeral = false;
+
+  // True if the user has gaia account.
+  bool has_gaia_account = false;
+};
+
+}  // namespace ash
+
+#endif  // ASH_PUBLIC_CPP_WALLPAPER_USER_INFO_H_
diff --git a/ash/public/interfaces/BUILD.gn b/ash/public/interfaces/BUILD.gn
index cd439c9..14536b5 100644
--- a/ash/public/interfaces/BUILD.gn
+++ b/ash/public/interfaces/BUILD.gn
@@ -38,7 +38,6 @@
     "login_screen.mojom",
     "media.mojom",
     "night_light_controller.mojom",
-    "note_taking_controller.mojom",
     "shelf_integration_test_api.mojom",
     "shutdown.mojom",
     "tablet_mode.mojom",
@@ -46,7 +45,6 @@
     "update.mojom",
     "voice_interaction_controller.mojom",
     "vpn_list.mojom",
-    "wallpaper.mojom",
     "window_pin_type.mojom",
     "window_properties.mojom",
   ]
diff --git a/ash/public/interfaces/note_taking_controller.mojom b/ash/public/interfaces/note_taking_controller.mojom
deleted file mode 100644
index a97e333..0000000
--- a/ash/public/interfaces/note_taking_controller.mojom
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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.
-
-module ash.mojom;
-
-// Interface for ash client (e.g. Chrome) to connect to the note taking
-// controller.
-interface NoteTakingController {
-  // Sets the client interface.
-  SetClient(NoteTakingControllerClient client);
-};
-
-// Interface for ash to notify the client (e.g. Chrome) about the new note
-// creation.
-interface NoteTakingControllerClient {
-  // Called when the controller needs to create a new note.
-  CreateNote();
-};
\ No newline at end of file
diff --git a/ash/public/interfaces/typemaps.gni b/ash/public/interfaces/typemaps.gni
index 7305cb5..085a6c0 100644
--- a/ash/public/interfaces/typemaps.gni
+++ b/ash/public/interfaces/typemaps.gni
@@ -2,7 +2,4 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-typemaps = [
-  "//ash/public/interfaces/shelf_integration_test_api.typemap",
-  "//ash/public/interfaces/wallpaper.typemap",
-]
+typemaps = [ "//ash/public/interfaces/shelf_integration_test_api.typemap" ]
diff --git a/ash/public/interfaces/wallpaper.mojom b/ash/public/interfaces/wallpaper.mojom
deleted file mode 100644
index 3e0d540..0000000
--- a/ash/public/interfaces/wallpaper.mojom
+++ /dev/null
@@ -1,343 +0,0 @@
-// Copyright 2016 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.
-
-module ash.mojom;
-
-import "components/account_id/interfaces/account_id.mojom";
-import "mojo/public/mojom/base/file_path.mojom";
-import "mojo/public/mojom/base/time.mojom";
-import "ui/gfx/image/mojo/image.mojom";
-import "url/mojom/url.mojom";
-
-// These values match ash::WallpaperLayout.
-enum WallpaperLayout {
-  CENTER,
-  CENTER_CROPPED,
-  STRETCH,
-  TILE,
-};
-
-// Matches user_manager::UserType.
-enum UserType {
-  // Regular user, has a user name and password.
-  REGULAR,
-
-  // Guest user, logs in without authentication.
-  GUEST,
-
-  // Public account user, logs in without authentication. Available only if
-  // enabled through policy.
-  PUBLIC_ACCOUNT,
-
-  // Supervised user, logs in only with local authentication.
-  SUPERVISED,
-
-  // Kiosk app robot, logs in without authentication.
-  KIOSK,
-
-  // Child user, with supervised options.
-  CHILD,
-
-  // Android app in kiosk mode, logs in without authentication.
-  ARC_KIOSK,
-
-  // Active Directory user. Authenticates against Active Directory server.
-  ACTIVE_DIRECTORY,
-};
-
-// User info needed to set wallpapers. Clients must specify the user because
-// it's not always the same with the active user, e.g., when showing wallpapers
-// for different user pods at login screen, or setting wallpapers selectively
-// for primary user and active user during a multi-profile session.
-struct WallpaperUserInfo {
-  // The user's account id.
-  signin.mojom.AccountId account_id;
-
-  // The user type.
-  UserType type;
-
-  // True if the user's non-cryptohome data (wallpaper, avatar etc.) is
-  // ephemeral. See |UserManager::IsCurrentUserNonCryptohomeDataEphemeral| for
-  // more details.
-  bool is_ephemeral;
-
-  // True if the user has gaia account.
-  bool has_gaia_account;
-};
-
-// Used by Chrome to set the wallpaper displayed by ash.
-interface WallpaperController {
-  // Do the initialization: Sets the client interface, the paths of wallpaper
-  // directories and the device wallpaper policy enforcement flag. The paths
-  // must be sent over IPC because chrome owns the concept of user data
-  // directory.
-  // |client|: The client interface.
-  // |user_data_path|: Directory where user data can be written.
-  // |chromeos_wallpapers_path|: Directory where downloaded chromeos wallpapers
-  //                             reside.
-  // |chromeos_custom_wallpapers_path|: Directory where custom wallpapers
-  //                                    reside.
-  // |device_policy_wallpaper_path|: The file path of the device policy
-  //                                 wallpaper (if any).
-  Init(WallpaperControllerClient client,
-       mojo_base.mojom.FilePath user_data_path,
-       mojo_base.mojom.FilePath chromeos_wallpapers_path,
-       mojo_base.mojom.FilePath chromeos_custom_wallpapers_path,
-       mojo_base.mojom.FilePath device_policy_wallpaper_path);
-
-  // Sets wallpaper from a local file and updates the saved wallpaper info for
-  // the user.
-  // |user_info|: The user's information related to wallpaper.
-  // |wallpaper_files_id|: The file id for user_info.account_id.
-  // |file_name|: The name of the wallpaper file.
-  // |layout|: The layout of the wallpaper, used for wallpaper resizing.
-  // |image|: The wallpaper image.
-  // |preview_mode|: If true, show the wallpaper immediately but doesn't change
-  //                 the user wallpaper info until |ConfirmPreviewWallpaper| is
-  //                 called.
-  SetCustomWallpaper(WallpaperUserInfo user_info,
-                     string wallpaper_files_id,
-                     string file_name,
-                     WallpaperLayout layout,
-                     gfx.mojom.ImageSkia image,
-                     bool preview_mode);
-
-  // Sets wallpaper from the Chrome OS wallpaper picker. If the wallpaper file
-  // corresponding to |url| already exists in local file system (i.e.
-  // |SetOnlineWallpaperFromData| was called earlier with the same |url|),
-  // returns true and sets wallpaper for the user, otherwise returns false.
-  // |user_info|: The user's information related to wallpaper.
-  // |url|: The wallpaper url.
-  // |layout|: The layout of the wallpaper, used for wallpaper resizing.
-  // |preview_mode|: If true, show the wallpaper immediately but doesn't change
-  //                 the user wallpaper info until |ConfirmPreviewWallpaper| is
-  //                 called.
-  // |file_exists|: If the wallpaper file exists in local file system.
-  SetOnlineWallpaperIfExists(WallpaperUserInfo user_info,
-                             string url,
-                             WallpaperLayout layout,
-                             bool preview_mode) => (bool file_exists);
-
-  // Sets wallpaper from the Chrome OS wallpaper picker and saves the wallpaper
-  // to local file system. After this, |SetOnlineWallpaperIfExists| will return
-  // true for the same |url|, so that there's no need to provide |image_data|
-  // when the same wallpaper needs to be set again or for another user.
-  // |user_info|: The user's information related to wallpaper.
-  // |url|: The wallpaper url.
-  // |layout|: The layout of the wallpaper, used for wallpaper resizing.
-  // |preview_mode|: If true, show the wallpaper immediately but doesn't change
-  //                 the user wallpaper info until |ConfirmPreviewWallpaper| is
-  //                 called.
-  // |success|: If the wallpaper is set successfully (i.e. no decoding error
-  //            etc.).
-  SetOnlineWallpaperFromData(WallpaperUserInfo user_info,
-                             string image_data,
-                             string url,
-                             WallpaperLayout layout,
-                             bool preview_mode) => (bool success);
-
-  // Sets the user's wallpaper to be the default wallpaper. Note: different user
-  // types may have different default wallpapers.
-  // |wallpaper_files_id|: The file id for user_info.account_id.
-  // |show_wallpaper|: If false, don't show the new wallpaper now but only
-  //                   update cache.
-  SetDefaultWallpaper(WallpaperUserInfo user_info,
-                      string wallpaper_files_id,
-                      bool show_wallpaper);
-
-  // Sets the paths of the customized default wallpaper to be used wherever a
-  // default wallpaper is needed. If a default wallpaper is being shown, updates
-  // the screen to replace the old default wallpaper. Note: it doesn't change
-  // the default wallpaper for guest and child accounts.
-  // |customized_default_small_path|: The file path of the small-size customized
-  //                                  default wallpaper, if any.
-  // |customized_default_large_path|: The file path of the large-size customized
-  //                                  default wallpaper, if any.
-  SetCustomizedDefaultWallpaperPaths(
-      mojo_base.mojom.FilePath customized_default_small_path,
-      mojo_base.mojom.FilePath customized_default_large_path);
-
-  // Sets wallpaper from policy. If the user has logged in, show the policy
-  // wallpaper immediately, otherwise, the policy wallpaper will be shown the
-  // next time |ShowUserWallpaper| is called. Note: it is different from device
-  // policy.
-  // |user_info|: The user's information related to wallpaper.
-  // |wallpaper_files_id|: The file id for user_info.account_id.
-  // |data|: The data used to decode the image.
-  SetPolicyWallpaper(WallpaperUserInfo user_info,
-                     string wallpaper_files_id,
-                     string data);
-
-  // Sets the path of device policy wallpaper.
-  // |device_policy_wallpaper_path|: The file path of the device policy
-  //                                 wallpaper if it was set or empty value if
-  //                                 it was cleared.
-  SetDevicePolicyWallpaperPath(
-      mojo_base.mojom.FilePath device_policy_wallpaper_path);
-
-  // Sets wallpaper from a third-party app (as opposed to the Chrome OS
-  // wallpaper picker).
-  // |user_info|: The user's information related to wallpaper.
-  // |wallpaper_files_id|: The file id for user_info.account_id.
-  // |file_name|: The name of the wallpaper file.
-  // |layout|: The layout of the wallpaper, used for wallpaper resizing.
-  // |image|: The wallpaper image.
-  // |allowed|: If the wallpaper is allowed to be shown on screen. It's false if
-  //            1) the user is not permitted to change wallpaper, or
-  //            2) updating the on-screen wallpaper is not allowed at the
-  //               given moment.
-  // |image_id|: A unique id assigned to the image. Clients may be interested in
-  //             observing all wallpaper changes and acting differently based on
-  //             if the wallpaper change is due to their own request. In order
-  //             to do so, they should compare this value with the one that's
-  //             returned by |OnWallpaperChanged|.
-  SetThirdPartyWallpaper(WallpaperUserInfo user_info,
-                         string wallpaper_files_id,
-                         string file_name,
-                         WallpaperLayout layout,
-                         gfx.mojom.ImageSkia image)
-                         => (bool allowed, uint32 image_id);
-
-  // Confirms the wallpaper being previewed to be set as the actual user
-  // wallpaper. Must be called in preview mode.
-  ConfirmPreviewWallpaper();
-
-  // Cancels the wallpaper preview and reverts to the user wallpaper. Must be
-  // called in preview mode.
-  CancelPreviewWallpaper();
-
-  // Updates the layout for the user's custom wallpaper and reloads the
-  // wallpaper with the new layout.
-  // |user_info|: The user's information related to wallpaper.
-  // |layout|: The new layout of the wallpaper.
-  UpdateCustomWallpaperLayout(WallpaperUserInfo user_info,
-                              WallpaperLayout layout);
-
-  // Shows the user's wallpaper, which is determined in the following order:
-  // 1) Use device policy wallpaper if it exists AND we are at the login screen.
-  // 2) Use user policy wallpaper if it exists.
-  // 3) Use the wallpaper set by the user (either by |SetOnlineWallpaper| or
-  //    |SetCustomWallpaper|), if any.
-  // 4) Use the default wallpaper of this user.
-  ShowUserWallpaper(WallpaperUserInfo user_info);
-
-  // Used by the gaia-signin UI. Signin wallpaper is considered either as the
-  // device policy wallpaper or the default wallpaper.
-  ShowSigninWallpaper();
-
-  // Shows a one-shot wallpaper, which does not belong to any particular user
-  // and is not saved to file. Note: the wallpaper will never be dimmed or
-  // blurred because it's assumed that the caller wants to show the image as is
-  // when using this method.
-  ShowOneShotWallpaper(gfx.mojom.ImageSkia image);
-
-  // Shows a wallpaper that stays on top of everything except for the power off
-  // animation. All other wallpaper requests are ignored when the always-on-top
-  // wallpaper is being shown.
-  // |image_path|: The file path to read the image data from.
-  ShowAlwaysOnTopWallpaper(mojo_base.mojom.FilePath image_path);
-
-  // Removes the always-on-top wallpaper. The wallpaper will revert to the
-  // previous one, or a default one if there was none. No-op if the current
-  // wallpaper is not always-on-top.
-  RemoveAlwaysOnTopWallpaper();
-
-  // Removes all of the user's saved wallpapers and related info.
-  // |wallpaper_files_id|: The file id for user_info.account_id.
-  RemoveUserWallpaper(WallpaperUserInfo user_info, string wallpaper_files_id);
-
-  // Removes all of the user's saved wallpapers and related info if the
-  // wallpaper was set by |SetPolicyWallpaper|. In addition, sets the user's
-  // wallpaper to be the default. If the user has logged in, show the default
-  // wallpaper immediately, otherwise, the default wallpaper will be shown the
-  // next time |ShowUserWallpaper| is called.
-  // |user_info|: The user's information related to wallpaper.
-  // |wallpaper_files_id|: The file id for user_info.account_id.
-  RemovePolicyWallpaper(WallpaperUserInfo user_info, string wallpaper_files_id);
-
-  // Returns the urls of the wallpapers that exist in local file system (i.e.
-  // |SetOnlineWallpaperFromData| was called earlier). The url is used as id
-  // to identify which wallpapers are available to be set offline.
-  GetOfflineWallpaperList() => (array<string> url_list);
-
-  // Sets wallpaper animation duration. Passing an empty value disables the
-  // animation.
-  SetAnimationDuration(mojo_base.mojom.TimeDelta animation_duration);
-
-  // Opens the wallpaper picker if the active user is not controlled by policy
-  // and it's allowed to change wallpaper per the user type and the login state.
-  OpenWallpaperPickerIfAllowed();
-
-  // Minimizes all windows except the active window.
-  // |user_id_hash|: The hash value corresponding to |User::username_hash|.
-  MinimizeInactiveWindows(string user_id_hash);
-
-  // Restores all minimized windows to their previous states. This should only
-  // be called after calling |MinimizeInactiveWindows|.
-  // |user_id_hash|: The hash value corresponding to |User::username_hash|.
-  RestoreMinimizedWindows(string user_id_hash);
-
-  // Calling this method triggers an initial notification of the wallpaper
-  // state. Observers are automatically removed as their connections are closed.
-  AddObserver(associated WallpaperObserver observer);
-
-  // Returns the wallpaper image currently being shown.
-  GetWallpaperImage() => (gfx.mojom.ImageSkia image);
-
-  // Returns the wallpaper prominent colors.
-  GetWallpaperColors() => (array<uint32> prominent_colors);
-
-  // Returns whether the current wallpaper is blurred.
-  IsWallpaperBlurred() => (bool blurred);
-
-  // Returns true if the wallpaper of the currently active user (if any) is
-  // controlled by policy (excluding device policy). If there's no active user,
-  // returns false.
-  IsActiveUserWallpaperControlledByPolicy() => (bool controlled);
-
-  // Returns the location and the layout of the active user's wallpaper. The
-  // location is either a url or a file path, corresponding to
-  // |WallpaperInfo.location|. Returns an empty string and an invalid layout if
-  // there's no active user.
-  GetActiveUserWallpaperInfo() => (string location, WallpaperLayout layout);
-
-  // Returns true if the wallpaper setting (used to open the wallpaper picker)
-  // should be visible.
-  ShouldShowWallpaperSetting() => (bool show);
-};
-
-// Used by ash to control a Chrome client.
-interface WallpaperControllerClient {
-  // Opens the wallpaper picker window.
-  OpenWallpaperPicker();
-
-  // Signals to the client that ash is ready to set wallpapers. The client is
-  // able to decide whatever the first wallpaper it wants to display.
-  OnReadyToSetWallpaper();
-
-  // Notifies the client that the animation of the first wallpaper since the
-  // controller initialization has completed.
-  // TODO(crbug.com/875128): Remove this after web-ui login code is completely
-  // removed.
-  OnFirstWallpaperAnimationFinished();
-};
-
-// Used to listen for wallpaper state changed.
-interface WallpaperObserver {
-  // Invoked when the wallpaper is changed. |image_id| is the unique id assigned
-  // to the current wallpaper image. It should only be used to compare against
-  // the value returned by a setting wallpaper request earlier
-  // (e.g. SetThirdPartyWallpaper). This value is unique to each |ImageSkia|
-  // object and is different for two objects with the same pixels.
-  OnWallpaperChanged(uint32 image_id);
-
-  // Invoked when the colors extracted from the current wallpaper change. Colors
-  // are ordered and are referenced in wallpaper::ColorProfileType.
-  OnWallpaperColorsChanged(array<uint32> prominent_colors);
-
-  // Invoked when the blur state of the wallpaper changes.
-  // TODO(crbug.com/875128): Remove this after web-ui login code is completely
-  // removed.
-  OnWallpaperBlurChanged(bool blurred);
-};
diff --git a/ash/public/interfaces/wallpaper.typemap b/ash/public/interfaces/wallpaper.typemap
deleted file mode 100644
index 01525b3..0000000
--- a/ash/public/interfaces/wallpaper.typemap
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright 2016 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.
-
-mojom = "//ash/public/interfaces/wallpaper.mojom"
-public_headers = [
-  "//ash/public/cpp/wallpaper_types.h",
-  "//components/user_manager/user_type.h",
-]
-traits_headers = [
-  "//ash/public/cpp/wallpaper_struct_traits.h",
-  "//ash/public/interfaces/user_info_traits.h",
-]
-public_deps = [
-  "//components/user_manager",
-]
-type_mappings = [
-  "ash.mojom.WallpaperLayout=ash::WallpaperLayout",
-  "ash.mojom.UserType=user_manager::UserType",
-]
diff --git a/ash/resources/vector_icons/BUILD.gn b/ash/resources/vector_icons/BUILD.gn
index 70dca18..8f116a99 100644
--- a/ash/resources/vector_icons/BUILD.gn
+++ b/ash/resources/vector_icons/BUILD.gn
@@ -177,7 +177,6 @@
     "system_menu_tablet.icon",
     "system_menu_tracing.icon",
     "system_menu_timer.icon",
-    "system_menu_update.icon",
     "system_menu_new_user.icon",
     "system_menu_night_light_off.icon",
     "system_menu_night_light_on.icon",
diff --git a/ash/resources/vector_icons/system_menu_update.icon b/ash/resources/vector_icons/system_menu_update.icon
deleted file mode 100644
index d96e6d9..0000000
--- a/ash/resources/vector_icons/system_menu_update.icon
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2016 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.
-
-CANVAS_DIMENSIONS, 40,
-MOVE_TO, 20, 36,
-R_CUBIC_TO, 8.84f, 0, 16, -7.16f, 16, -16,
-CUBIC_TO_SHORTHAND, 28.84f, 4, 20, 4,
-CUBIC_TO_SHORTHAND, 4, 11.16f, 4, 20,
-R_CUBIC_TO, 0, 8.84f, 7.16f, 16, 16, 16,
-CLOSE,
-R_MOVE_TO, -4, -7,
-R_H_LINE_TO, 8,
-R_V_LINE_TO, -6,
-R_H_LINE_TO, 6,
-LINE_TO, 20, 11,
-LINE_TO, 10, 23,
-R_H_LINE_TO, 6,
-R_V_LINE_TO, 6,
-CLOSE
-
-CANVAS_DIMENSIONS, 20,
-MOVE_TO, 10, 18,
-R_CUBIC_TO, 4.42f, 0, 8, -3.58f, 8, -8,
-R_CUBIC_TO, 0, -4.42f, -3.58f, -8, -8, -8,
-R_CUBIC_TO, -4.42f, 0, -8, 3.58f, -8, 8,
-R_CUBIC_TO, 0, 4.42f, 3.58f, 8, 8, 8,
-CLOSE,
-R_MOVE_TO, -2, -4,
-R_H_LINE_TO, 4,
-R_V_LINE_TO, -3,
-R_H_LINE_TO, 3,
-R_LINE_TO, -5, -6,
-R_LINE_TO, -5, 6,
-R_H_LINE_TO, 3,
-R_V_LINE_TO, 3,
-CLOSE
diff --git a/ash/shelf/shelf_background_animator.cc b/ash/shelf/shelf_background_animator.cc
index 79f24ba..7b03596 100644
--- a/ash/shelf/shelf_background_animator.cc
+++ b/ash/shelf/shelf_background_animator.cc
@@ -13,7 +13,7 @@
 #include "ash/shelf/shelf.h"
 #include "ash/shelf/shelf_background_animator_observer.h"
 #include "ash/shelf/shelf_constants.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "ui/gfx/animation/slide_animation.h"
 #include "ui/gfx/color_analysis.h"
 #include "ui/gfx/color_palette.h"
@@ -57,7 +57,7 @@
 ShelfBackgroundAnimator::ShelfBackgroundAnimator(
     ShelfBackgroundType background_type,
     Shelf* shelf,
-    WallpaperController* wallpaper_controller)
+    WallpaperControllerImpl* wallpaper_controller)
     : shelf_(shelf), wallpaper_controller_(wallpaper_controller) {
   if (wallpaper_controller_)
     wallpaper_controller_->AddObserver(this);
diff --git a/ash/shelf/shelf_background_animator.h b/ash/shelf/shelf_background_animator.h
index 022fbeb..d43884c 100644
--- a/ash/shelf/shelf_background_animator.h
+++ b/ash/shelf/shelf_background_animator.h
@@ -10,8 +10,8 @@
 
 #include "ash/ash_export.h"
 #include "ash/public/cpp/shelf_types.h"
+#include "ash/public/cpp/wallpaper_controller_observer.h"
 #include "ash/shelf/shelf_observer.h"
-#include "ash/wallpaper/wallpaper_controller_observer.h"
 #include "base/macros.h"
 #include "base/observer_list.h"
 #include "third_party/skia/include/core/SkColor.h"
@@ -27,7 +27,7 @@
 class Shelf;
 class ShelfBackgroundAnimatorObserver;
 class ShelfBackgroundAnimatorTestApi;
-class WallpaperController;
+class WallpaperControllerImpl;
 
 // Central controller for the Shelf and Dock opacity animations.
 //
@@ -51,7 +51,7 @@
   // wallpaper changes if not null.
   ShelfBackgroundAnimator(ShelfBackgroundType background_type,
                           Shelf* shelf,
-                          WallpaperController* wallpaper_controller);
+                          WallpaperControllerImpl* wallpaper_controller);
   ~ShelfBackgroundAnimator() override;
 
   ShelfBackgroundType target_background_type() const {
@@ -159,7 +159,7 @@
   Shelf* shelf_;
 
   // The wallpaper controller to observe for changes and to extract colors from.
-  WallpaperController* wallpaper_controller_;
+  WallpaperControllerImpl* wallpaper_controller_;
 
   // The background type that this is animating towards or has reached.
   ShelfBackgroundType target_background_type_ = SHELF_BACKGROUND_DEFAULT;
diff --git a/ash/shelf/shelf_context_menu_model.cc b/ash/shelf/shelf_context_menu_model.cc
index 38c578f..0117a53 100644
--- a/ash/shelf/shelf_context_menu_model.cc
+++ b/ash/shelf/shelf_context_menu_model.cc
@@ -21,7 +21,7 @@
 #include "ash/session/session_controller_impl.h"
 #include "ash/shell.h"
 #include "ash/strings/grit/ash_strings.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
 #include "base/metrics/user_metrics.h"
 #include "base/numerics/safe_conversions.h"
diff --git a/ash/shelf/shelf_context_menu_model_unittest.cc b/ash/shelf/shelf_context_menu_model_unittest.cc
index 70397b9..6d239a3c 100644
--- a/ash/shelf/shelf_context_menu_model_unittest.cc
+++ b/ash/shelf/shelf_context_menu_model_unittest.cc
@@ -6,12 +6,13 @@
 
 #include "ash/public/cpp/app_menu_constants.h"
 #include "ash/public/cpp/shelf_item_delegate.h"
+#include "ash/public/cpp/wallpaper_controller_client.h"
 #include "ash/session/test_session_controller_client.h"
 #include "ash/shelf/shelf.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
 #include "ash/test_shell_delegate.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
 #include "base/strings/utf_string_conversions.h"
 #include "ui/display/display.h"
@@ -40,27 +41,20 @@
 };
 
 // A test wallpaper controller client class.
-class TestWallpaperControllerClient : public mojom::WallpaperControllerClient {
+class TestWallpaperControllerClient : public WallpaperControllerClient {
  public:
-  TestWallpaperControllerClient() : binding_(this) {}
-  ~TestWallpaperControllerClient() override = default;
+  TestWallpaperControllerClient() = default;
+  ~TestWallpaperControllerClient() = default;
 
   size_t open_count() const { return open_count_; }
 
-  mojom::WallpaperControllerClientPtr CreateInterfacePtr() {
-    mojom::WallpaperControllerClientPtr ptr;
-    binding_.Bind(mojo::MakeRequest(&ptr));
-    return ptr;
-  }
-
-  // mojom::WallpaperControllerClient:
+  // WallpaperControllerClient:
   void OpenWallpaperPicker() override { open_count_++; }
   void OnReadyToSetWallpaper() override {}
   void OnFirstWallpaperAnimationFinished() override {}
 
  private:
   size_t open_count_ = 0;
-  mojo::Binding<mojom::WallpaperControllerClient> binding_;
 
   DISALLOW_COPY_AND_ASSIGN(TestWallpaperControllerClient);
 };
@@ -147,13 +141,11 @@
   EXPECT_TRUE(submenu->IsItemCheckedAt(0));
 
   TestWallpaperControllerClient client;
-  Shell::Get()->wallpaper_controller()->SetClientForTesting(
-      client.CreateInterfacePtr());
+  Shell::Get()->wallpaper_controller()->SetClientForTesting(&client);
   EXPECT_EQ(0u, client.open_count());
 
   // Click the third option, wallpaper picker. It should open.
   menu3.ActivatedAt(2);
-  Shell::Get()->wallpaper_controller()->FlushForTesting();
   EXPECT_EQ(1u, client.open_count());
 }
 
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc
index b41962a0..e96a726 100644
--- a/ash/shelf/shelf_layout_manager.cc
+++ b/ash/shelf/shelf_layout_manager.cc
@@ -30,7 +30,7 @@
 #include "ash/shell.h"
 #include "ash/system/locale/locale_update_controller.h"
 #include "ash/system/status_area_widget.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "ash/wm/fullscreen_window_finder.h"
 #include "ash/wm/lock_state_controller.h"
 #include "ash/wm/mru_window_tracker.h"
diff --git a/ash/shelf/shelf_layout_manager.h b/ash/shelf/shelf_layout_manager.h
index 1c72070..c93365c 100644
--- a/ash/shelf/shelf_layout_manager.h
+++ b/ash/shelf/shelf_layout_manager.h
@@ -11,12 +11,12 @@
 #include "ash/ash_export.h"
 #include "ash/home_screen/home_launcher_gesture_handler_observer.h"
 #include "ash/public/cpp/shelf_types.h"
+#include "ash/public/cpp/wallpaper_controller_observer.h"
 #include "ash/rotator/screen_rotation_animator_observer.h"
 #include "ash/session/session_observer.h"
 #include "ash/shelf/shelf.h"
 #include "ash/shell_observer.h"
 #include "ash/system/locale/locale_update_controller.h"
-#include "ash/wallpaper/wallpaper_controller_observer.h"
 #include "ash/wm/lock_state_observer.h"
 #include "ash/wm/overview/overview_observer.h"
 #include "ash/wm/wm_snap_to_pixel_layout_manager.h"
@@ -45,6 +45,7 @@
 class ShelfLayoutManagerObserver;
 class ShelfLayoutManagerTest;
 class ShelfWidget;
+class WallpaperController;
 
 // ShelfLayoutManager is the layout manager responsible for the shelf and
 // status widgets. The shelf is given the total available width and told the
diff --git a/ash/shelf/shelf_layout_manager_unittest.cc b/ash/shelf/shelf_layout_manager_unittest.cc
index 47f2bf3c..475f414 100644
--- a/ash/shelf/shelf_layout_manager_unittest.cc
+++ b/ash/shelf/shelf_layout_manager_unittest.cc
@@ -26,6 +26,7 @@
 #include "ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.h"
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/public/cpp/test/shell_test_api.h"
+#include "ash/public/cpp/wallpaper_controller_observer.h"
 #include "ash/public/cpp/window_properties.h"
 #include "ash/root_window_controller.h"
 #include "ash/screen_util.h"
@@ -41,7 +42,7 @@
 #include "ash/system/status_area_widget_test_helper.h"
 #include "ash/system/unified/unified_system_tray.h"
 #include "ash/test/ash_test_base.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "ash/window_factory.h"
 #include "ash/wm/lock_state_controller.h"
 #include "ash/wm/overview/overview_controller.h"
@@ -1263,8 +1264,7 @@
 // Assertions around the login screen.
 TEST_F(ShelfLayoutManagerTest, VisibleWhenLoginScreenShowing) {
   Shelf* shelf = GetPrimaryShelf();
-  WallpaperController* wallpaper_controller =
-      Shell::Get()->wallpaper_controller();
+  auto* wallpaper_controller = Shell::Get()->wallpaper_controller();
   WallpaperShownWaiter waiter;
 
   SessionInfo info;
diff --git a/ash/shelf/shelf_view_unittest.cc b/ash/shelf/shelf_view_unittest.cc
index 854765e63..e9cb7e7 100644
--- a/ash/shelf/shelf_view_unittest.cc
+++ b/ash/shelf/shelf_view_unittest.cc
@@ -46,7 +46,7 @@
 #include "ash/test/ash_test_base.h"
 #include "ash/test/ash_test_helper.h"
 #include "ash/test_shell_delegate.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "ash/wallpaper/wallpaper_controller_test_api.h"
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
 #include "base/i18n/rtl.h"
diff --git a/ash/shell.cc b/ash/shell.cc
index a3c8640..063bb6f 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -65,7 +65,6 @@
 #include "ash/media/media_controller.h"
 #include "ash/media/media_notification_controller_impl.h"
 #include "ash/multi_device_setup/multi_device_notification_presenter.h"
-#include "ash/note_taking_controller.h"
 #include "ash/policy/policy_recommendation_restorer.h"
 #include "ash/public/cpp/ash_constants.h"
 #include "ash/public/cpp/ash_features.h"
@@ -121,7 +120,7 @@
 #include "ash/tray_action/tray_action.h"
 #include "ash/utility/screenshot_controller.h"
 #include "ash/voice_interaction/voice_interaction_controller.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "ash/wayland/wayland_server_controller.h"
 #include "ash/wm/ash_focus_rules.h"
 #include "ash/wm/container_finder.h"
@@ -556,7 +555,6 @@
       locale_update_controller_(std::make_unique<LocaleUpdateController>()),
       media_controller_(std::make_unique<MediaController>(connector)),
       session_controller_(std::make_unique<SessionControllerImpl>()),
-      note_taking_controller_(std::make_unique<NoteTakingController>()),
       shell_delegate_(std::move(shell_delegate)),
       shell_state_(std::make_unique<ShellState>()),
       shutdown_controller_(std::make_unique<ShutdownController>()),
@@ -911,7 +909,8 @@
   // Shelf, and WallPaper could be created by the factory.
   views::FocusManagerFactory::Install(new AshFocusManagerFactory);
 
-  wallpaper_controller_ = std::make_unique<WallpaperController>(local_state_);
+  wallpaper_controller_ =
+      std::make_unique<WallpaperControllerImpl>(local_state_);
 
   window_positioner_ = std::make_unique<WindowPositioner>();
 
diff --git a/ash/shell.h b/ash/shell.h
index b80352d..39245a3 100644
--- a/ash/shell.h
+++ b/ash/shell.h
@@ -143,7 +143,6 @@
 class MruWindowTracker;
 class MultiDeviceNotificationPresenter;
 class NightLightController;
-class NoteTakingController;
 class OverlayEventFilter;
 class OverviewController;
 class PartialMagnificationController;
@@ -189,7 +188,7 @@
 class VideoDetector;
 class VoiceInteractionController;
 class VpnList;
-class WallpaperController;
+class WallpaperControllerImpl;
 class WaylandServerController;
 class WindowCycleController;
 class WindowPositioner;
@@ -415,9 +414,6 @@
   }
   MruWindowTracker* mru_window_tracker() { return mru_window_tracker_.get(); }
   NightLightController* night_light_controller();
-  NoteTakingController* note_taking_controller() {
-    return note_taking_controller_.get();
-  }
   OverlayEventFilter* overlay_filter() { return overlay_filter_.get(); }
   PartialMagnificationController* partial_magnification_controller() {
     return partial_magnification_controller_.get();
@@ -500,7 +496,7 @@
     return voice_interaction_controller_.get();
   }
   VpnList* vpn_list() { return vpn_list_.get(); }
-  WallpaperController* wallpaper_controller() {
+  WallpaperControllerImpl* wallpaper_controller() {
     return wallpaper_controller_.get();
   }
   WindowCycleController* window_cycle_controller() {
@@ -682,7 +678,6 @@
   std::unique_ptr<ResizeShadowController> resize_shadow_controller_;
   std::unique_ptr<SessionControllerImpl> session_controller_;
   std::unique_ptr<NightLightController> night_light_controller_;
-  std::unique_ptr<NoteTakingController> note_taking_controller_;
   std::unique_ptr<PolicyRecommendationRestorer> policy_recommendation_restorer_;
   std::unique_ptr<ScreenSwitchCheckController> screen_switch_check_controller_;
   std::unique_ptr<ShelfController> shelf_controller_;
@@ -698,7 +693,7 @@
   std::unique_ptr<TrayAction> tray_action_;
   std::unique_ptr<VoiceInteractionController> voice_interaction_controller_;
   std::unique_ptr<VpnList> vpn_list_;
-  std::unique_ptr<WallpaperController> wallpaper_controller_;
+  std::unique_ptr<WallpaperControllerImpl> wallpaper_controller_;
   std::unique_ptr<WindowCycleController> window_cycle_controller_;
   std::unique_ptr<OverviewController> overview_controller_;
   // Owned by |focus_controller_|.
diff --git a/ash/system/palette/tools/create_note_action.cc b/ash/system/palette/tools/create_note_action.cc
index 236b193..73710ef 100644
--- a/ash/system/palette/tools/create_note_action.cc
+++ b/ash/system/palette/tools/create_note_action.cc
@@ -4,7 +4,7 @@
 
 #include "ash/system/palette/tools/create_note_action.h"
 
-#include "ash/note_taking_controller.h"
+#include "ash/public/cpp/note_taking_client.h"
 #include "ash/resources/vector_icons/vector_icons.h"
 #include "ash/shell.h"
 #include "ash/strings/grit/ash_strings.h"
@@ -12,6 +12,14 @@
 #include "ui/base/l10n/l10n_util.h"
 
 namespace ash {
+namespace {
+NoteTakingClient* GetAvailableClient() {
+  auto* client = NoteTakingClient::GetInstance();
+  if (!client || !client->CanCreateNote())
+    return nullptr;
+  return client;
+}
+}  // namespace
 
 CreateNoteAction::CreateNoteAction(Delegate* delegate)
     : CommonPaletteTool(delegate) {}
@@ -29,14 +37,16 @@
 void CreateNoteAction::OnEnable() {
   CommonPaletteTool::OnEnable();
 
-  Shell::Get()->note_taking_controller()->CreateNote();
+  auto* client = GetAvailableClient();
+  if (client)
+    client->CreateNote();
 
   delegate()->DisableTool(GetToolId());
   delegate()->HidePalette();
 }
 
 views::View* CreateNoteAction::CreateView() {
-  if (!Shell::Get()->note_taking_controller()->CanCreateNote())
+  if (!GetAvailableClient())
     return nullptr;
 
   return CreateDefaultView(
diff --git a/ash/system/palette/tools/create_note_unittest.cc b/ash/system/palette/tools/create_note_unittest.cc
index 274000eaf..e2982b62 100644
--- a/ash/system/palette/tools/create_note_unittest.cc
+++ b/ash/system/palette/tools/create_note_unittest.cc
@@ -4,8 +4,7 @@
 
 #include <memory>
 
-#include "ash/note_taking_controller.h"
-#include "ash/shell.h"
+#include "ash/public/cpp/note_taking_client.h"
 #include "ash/system/palette/mock_palette_tool_delegate.h"
 #include "ash/system/palette/palette_ids.h"
 #include "ash/system/palette/palette_tool.h"
@@ -17,48 +16,25 @@
 
 namespace ash {
 
-class TestNoteTakingControllerClient
-    : public ash::mojom::NoteTakingControllerClient {
+class TestNoteTakingControllerClient : public NoteTakingClient {
  public:
-  TestNoteTakingControllerClient() : binding_(this) {}
+  TestNoteTakingControllerClient() = default;
   ~TestNoteTakingControllerClient() override = default;
 
-  void Attach() {
-    DCHECK(!controller_);
-    Shell::Get()->note_taking_controller()->BindRequest(
-        mojo::MakeRequest(&controller_));
-    ash::mojom::NoteTakingControllerClientPtr client;
-    binding_.Bind(mojo::MakeRequest(&client));
-    controller_->SetClient(std::move(client));
-    controller_.FlushForTesting();
-  }
-
-  void Detach() {
-    DCHECK(controller_);
-    controller_ = nullptr;
-    DCHECK(binding_.is_bound());
-    binding_.Close();
-    FlushClientMojo();
-  }
-
   int GetCreateNoteCount() {
-    FlushClientMojo();
     return create_note_count_;
   }
 
-  // ash::mojom::NoteTakingControllerClient:
+  void set_can_create(bool can_create) { can_create_ = can_create; }
+
+  // NoteTakingClient:
+  bool CanCreateNote() override { return can_create_; }
   void CreateNote() override { create_note_count_++; }
 
  private:
-  void FlushClientMojo() {
-    Shell::Get()->note_taking_controller()->FlushMojoForTesting();
-  }
-
+  bool can_create_ = true;
   int create_note_count_ = 0;
 
-  mojo::Binding<ash::mojom::NoteTakingControllerClient> binding_;
-  ash::mojom::NoteTakingControllerPtr controller_;
-
   DISALLOW_COPY_AND_ASSIGN(TestNoteTakingControllerClient);
 };
 
@@ -75,13 +51,11 @@
 
     palette_tool_delegate_ = std::make_unique<MockPaletteToolDelegate>();
     tool_ = std::make_unique<CreateNoteAction>(palette_tool_delegate_.get());
-    note_taking_client_ = std::make_unique<TestNoteTakingControllerClient>();
   }
 
  protected:
   std::unique_ptr<MockPaletteToolDelegate> palette_tool_delegate_;
   std::unique_ptr<PaletteTool> tool_;
-  std::unique_ptr<TestNoteTakingControllerClient> note_taking_client_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(CreateNoteTest);
@@ -94,12 +68,16 @@
   EXPECT_FALSE(tool_->CreateView());
   tool_->OnViewDestroyed();
 
-  note_taking_client_->Attach();
+  auto note_taking_client = std::make_unique<TestNoteTakingControllerClient>();
   std::unique_ptr<views::View> view = base::WrapUnique(tool_->CreateView());
   EXPECT_TRUE(view);
   tool_->OnViewDestroyed();
 
-  note_taking_client_->Detach();
+  note_taking_client->set_can_create(false);
+  EXPECT_FALSE(tool_->CreateView());
+  tool_->OnViewDestroyed();
+
+  note_taking_client.reset();
   EXPECT_FALSE(tool_->CreateView());
   tool_->OnViewDestroyed();
 }
@@ -107,7 +85,7 @@
 // Activating the note tool both creates a note on the client and also
 // disables the tool and hides the palette.
 TEST_F(CreateNoteTest, EnablingToolCreatesNewNoteAndDisablesTool) {
-  note_taking_client_->Attach();
+  auto note_taking_client = std::make_unique<TestNoteTakingControllerClient>();
   std::unique_ptr<views::View> view = base::WrapUnique(tool_->CreateView());
 
   EXPECT_CALL(*palette_tool_delegate_.get(),
@@ -115,7 +93,34 @@
   EXPECT_CALL(*palette_tool_delegate_.get(), HidePalette());
 
   tool_->OnEnable();
-  EXPECT_EQ(1, note_taking_client_->GetCreateNoteCount());
+  EXPECT_EQ(1, note_taking_client->GetCreateNoteCount());
+}
+
+TEST_F(CreateNoteTest, ClientGetsDisabledAfterViewCreated) {
+  auto note_taking_client = std::make_unique<TestNoteTakingControllerClient>();
+  std::unique_ptr<views::View> view = base::WrapUnique(tool_->CreateView());
+
+  EXPECT_CALL(*palette_tool_delegate_.get(),
+              DisableTool(PaletteToolId::CREATE_NOTE));
+  EXPECT_CALL(*palette_tool_delegate_.get(), HidePalette());
+
+  note_taking_client->set_can_create(false);
+
+  tool_->OnEnable();
+  EXPECT_EQ(0, note_taking_client->GetCreateNoteCount());
+}
+
+TEST_F(CreateNoteTest, ClientGetsRemovedAfterViewCreated) {
+  auto note_taking_client = std::make_unique<TestNoteTakingControllerClient>();
+  std::unique_ptr<views::View> view = base::WrapUnique(tool_->CreateView());
+
+  EXPECT_CALL(*palette_tool_delegate_.get(),
+              DisableTool(PaletteToolId::CREATE_NOTE));
+  EXPECT_CALL(*palette_tool_delegate_.get(), HidePalette());
+
+  note_taking_client.reset();
+
+  tool_->OnEnable();
 }
 
 }  // namespace ash
diff --git a/ash/system/unified/unified_system_tray.cc b/ash/system/unified/unified_system_tray.cc
index 3537af9..3abfd0b8 100644
--- a/ash/system/unified/unified_system_tray.cc
+++ b/ash/system/unified/unified_system_tray.cc
@@ -57,6 +57,11 @@
   void SetTrayBubbleHeight(int height) {
     popup_alignment_delegate_->SetTrayBubbleHeight(height);
   }
+  message_center::MessagePopupView* GetPopupViewForNotificationID(
+      const std::string& notification_id) {
+    return message_popup_collection_->GetPopupViewForNotificationID(
+        notification_id);
+  }
 
  private:
   std::unique_ptr<MessageCenterUiController> ui_controller_;
@@ -327,4 +332,10 @@
   quiet_mode_view_->Update();
 }
 
+message_center::MessagePopupView*
+UnifiedSystemTray::GetPopupViewForNotificationID(
+    const std::string& notification_id) {
+  return ui_delegate_->GetPopupViewForNotificationID(notification_id);
+}
+
 }  // namespace ash
diff --git a/ash/system/unified/unified_system_tray.h b/ash/system/unified/unified_system_tray.h
index ab63233..7a27a65 100644
--- a/ash/system/unified/unified_system_tray.h
+++ b/ash/system/unified/unified_system_tray.h
@@ -12,6 +12,10 @@
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 
+namespace message_center {
+class MessagePopupView;
+}  // namespace message_center
+
 namespace ash {
 
 namespace tray {
@@ -119,6 +123,10 @@
   void UpdateNotificationInternal();
   void UpdateNotificationAfterDelay();
 
+  // Forwarded to UiDelegate.
+  message_center::MessagePopupView* GetPopupViewForNotificationID(
+      const std::string& notification_id);
+
   const std::unique_ptr<UiDelegate> ui_delegate_;
 
   std::unique_ptr<UnifiedSystemTrayBubble> bubble_;
diff --git a/ash/system/unified/unified_system_tray_test_api.cc b/ash/system/unified/unified_system_tray_test_api.cc
index 40460240..d3bd0bc 100644
--- a/ash/system/unified/unified_system_tray_test_api.cc
+++ b/ash/system/unified/unified_system_tray_test_api.cc
@@ -84,6 +84,12 @@
   return type == base::k24HourClock;
 }
 
+message_center::MessagePopupView*
+UnifiedSystemTrayTestApi::GetPopupViewForNotificationID(
+    const std::string& notification_id) {
+  return tray_->GetPopupViewForNotificationID(notification_id);
+}
+
 views::View* UnifiedSystemTrayTestApi::GetBubbleView(int view_id) const {
   return tray_->bubble_->bubble_view_->GetViewByID(view_id);
 }
diff --git a/ash/system/unified/unified_system_tray_test_api.h b/ash/system/unified/unified_system_tray_test_api.h
index 5671fb4..0da485d 100644
--- a/ash/system/unified/unified_system_tray_test_api.h
+++ b/ash/system/unified/unified_system_tray_test_api.h
@@ -18,6 +18,10 @@
 class View;
 }  // namespace views
 
+namespace message_center {
+class MessagePopupView;
+}  // namespace message_center
+
 namespace ash {
 
 class UnifiedSystemTray;
@@ -41,6 +45,9 @@
   base::string16 GetBubbleViewTooltip(int view_id) override;
   bool Is24HourClock() override;
 
+  message_center::MessagePopupView* GetPopupViewForNotificationID(
+      const std::string& notification_id);
+
  private:
   // Returns a view in the bubble menu (not the tray itself). Returns null if
   // not found.
diff --git a/ash/system/update/update_notification_controller.cc b/ash/system/update/update_notification_controller.cc
index 0cec49af6..1f2814c6e2 100644
--- a/ash/system/update/update_notification_controller.cc
+++ b/ash/system/update/update_notification_controller.cc
@@ -11,6 +11,7 @@
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/system/model/system_tray_model.h"
 #include "base/bind.h"
+#include "components/vector_icons/vector_icons.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/message_center/message_center.h"
 #include "ui/message_center/public/cpp/notification.h"
@@ -62,7 +63,8 @@
           base::BindRepeating(
               &UpdateNotificationController::HandleNotificationClick,
               weak_ptr_factory_.GetWeakPtr())),
-      model_->rollback() ? kSystemMenuRollbackIcon : kSystemMenuUpdateIcon,
+      model_->rollback() ? kSystemMenuRollbackIcon
+                         : vector_icons::kBusinessIcon,
       warning_level);
   notification->set_pinned(true);
 
diff --git a/ash/test/ash_test_helper.cc b/ash/test/ash_test_helper.cc
index 1f42194..b545db8 100644
--- a/ash/test/ash_test_helper.cc
+++ b/ash/test/ash_test_helper.cc
@@ -26,7 +26,7 @@
 #include "ash/system/screen_layout_observer.h"
 #include "ash/test/ash_test_views_delegate.h"
 #include "ash/test_shell_delegate.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "ash/wm/overview/overview_controller.h"
 #include "base/bind.h"
 #include "base/run_loop.h"
diff --git a/ash/wallpaper/wallpaper_base_view.cc b/ash/wallpaper/wallpaper_base_view.cc
index ffc2e4be0..a792f97 100644
--- a/ash/wallpaper/wallpaper_base_view.cc
+++ b/ash/wallpaper/wallpaper_base_view.cc
@@ -7,7 +7,7 @@
 #include "ash/public/cpp/login_constants.h"
 #include "ash/public/cpp/wallpaper_types.h"
 #include "ash/shell.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "ash/wm/overview/overview_controller.h"
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
 #include "ui/gfx/canvas.h"
@@ -62,7 +62,7 @@
   // to fill the wallpaper. Ideally the image should be larger than the largest
   // display supported, if not we will scale and center it if the layout is
   // WALLPAPER_LAYOUT_CENTER_CROPPED.
-  WallpaperController* controller = Shell::Get()->wallpaper_controller();
+  auto* controller = Shell::Get()->wallpaper_controller();
   gfx::ImageSkia wallpaper = controller->GetWallpaper();
   WallpaperLayout layout = controller->GetWallpaperLayout();
 
diff --git a/ash/wallpaper/wallpaper_controller.cc b/ash/wallpaper/wallpaper_controller_impl.cc
similarity index 77%
rename from ash/wallpaper/wallpaper_controller.cc
rename to ash/wallpaper/wallpaper_controller_impl.cc
index 587ea0d..4aded0b1 100644
--- a/ash/wallpaper/wallpaper_controller.cc
+++ b/ash/wallpaper/wallpaper_controller_impl.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 "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 
 #include <memory>
 #include <numeric>
@@ -14,11 +14,12 @@
 #include "ash/public/cpp/ash_switches.h"
 #include "ash/public/cpp/login_constants.h"
 #include "ash/public/cpp/shell_window_ids.h"
+#include "ash/public/cpp/wallpaper_controller_client.h"
+#include "ash/public/cpp/wallpaper_controller_observer.h"
 #include "ash/root_window_controller.h"
 #include "ash/session/session_controller_impl.h"
 #include "ash/shell.h"
 #include "ash/shell_delegate.h"
-#include "ash/wallpaper/wallpaper_controller_observer.h"
 #include "ash/wallpaper/wallpaper_utils/wallpaper_color_calculator.h"
 #include "ash/wallpaper/wallpaper_utils/wallpaper_decoder.h"
 #include "ash/wallpaper/wallpaper_utils/wallpaper_resizer.h"
@@ -121,21 +122,21 @@
 }
 
 // Returns the appropriate wallpaper resolution for all root windows.
-WallpaperController::WallpaperResolution GetAppropriateResolution() {
-  gfx::Size size = WallpaperController::GetMaxDisplaySizeInNative();
+WallpaperControllerImpl::WallpaperResolution GetAppropriateResolution() {
+  gfx::Size size = WallpaperControllerImpl::GetMaxDisplaySizeInNative();
   return (size.width() > kSmallWallpaperMaxWidth ||
           size.height() > kSmallWallpaperMaxHeight)
-             ? WallpaperController::WALLPAPER_RESOLUTION_LARGE
-             : WallpaperController::WALLPAPER_RESOLUTION_SMALL;
+             ? WallpaperControllerImpl::WALLPAPER_RESOLUTION_LARGE
+             : WallpaperControllerImpl::WALLPAPER_RESOLUTION_SMALL;
 }
 
 // Returns the path of the online wallpaper corresponding to |url| and
 // |resolution|.
 base::FilePath GetOnlineWallpaperPath(
     const std::string& url,
-    WallpaperController::WallpaperResolution resolution) {
+    WallpaperControllerImpl::WallpaperResolution resolution) {
   std::string file_name = GURL(url).ExtractFileName();
-  if (resolution == WallpaperController::WALLPAPER_RESOLUTION_SMALL) {
+  if (resolution == WallpaperControllerImpl::WALLPAPER_RESOLUTION_SMALL) {
     file_name = base::FilePath(file_name)
                     .InsertBeforeExtension(kSmallWallpaperSuffix)
                     .value();
@@ -146,11 +147,11 @@
 
 // Returns wallpaper subdirectory name for current resolution.
 std::string GetCustomWallpaperSubdirForCurrentResolution() {
-  WallpaperController::WallpaperResolution resolution =
+  WallpaperControllerImpl::WallpaperResolution resolution =
       GetAppropriateResolution();
-  return resolution == WallpaperController::WALLPAPER_RESOLUTION_SMALL
-             ? WallpaperController::kSmallWallpaperSubDir
-             : WallpaperController::kLargeWallpaperSubDir;
+  return resolution == WallpaperControllerImpl::WALLPAPER_RESOLUTION_SMALL
+             ? WallpaperControllerImpl::kSmallWallpaperSubDir
+             : WallpaperControllerImpl::kLargeWallpaperSubDir;
 }
 
 // Resizes |image| to a resolution which is nearest to |preferred_width| and
@@ -294,21 +295,21 @@
 // Creates all new custom wallpaper directories for |wallpaper_files_id| if they
 // don't exist.
 void EnsureCustomWallpaperDirectories(const std::string& wallpaper_files_id) {
-  base::FilePath dir = WallpaperController::GetCustomWallpaperDir(
-                           WallpaperController::kSmallWallpaperSubDir)
+  base::FilePath dir = WallpaperControllerImpl::GetCustomWallpaperDir(
+                           WallpaperControllerImpl::kSmallWallpaperSubDir)
                            .Append(wallpaper_files_id);
   if (!base::PathExists(dir))
     base::CreateDirectory(dir);
 
-  dir = WallpaperController::GetCustomWallpaperDir(
-            WallpaperController::kLargeWallpaperSubDir)
+  dir = WallpaperControllerImpl::GetCustomWallpaperDir(
+            WallpaperControllerImpl::kLargeWallpaperSubDir)
             .Append(wallpaper_files_id);
 
   if (!base::PathExists(dir))
     base::CreateDirectory(dir);
 
-  dir = WallpaperController::GetCustomWallpaperDir(
-            WallpaperController::kOriginalWallpaperSubDir)
+  dir = WallpaperControllerImpl::GetCustomWallpaperDir(
+            WallpaperControllerImpl::kOriginalWallpaperSubDir)
             .Append(wallpaper_files_id);
   if (!base::PathExists(dir))
     base::CreateDirectory(dir);
@@ -320,27 +321,27 @@
                          const base::FilePath& original_path,
                          WallpaperLayout layout,
                          gfx::ImageSkia image) {
-  base::DeleteFile(WallpaperController::GetCustomWallpaperDir(
-                       WallpaperController::kOriginalWallpaperSubDir)
+  base::DeleteFile(WallpaperControllerImpl::GetCustomWallpaperDir(
+                       WallpaperControllerImpl::kOriginalWallpaperSubDir)
                        .Append(wallpaper_files_id),
                    true /* recursive */);
-  base::DeleteFile(WallpaperController::GetCustomWallpaperDir(
-                       WallpaperController::kSmallWallpaperSubDir)
+  base::DeleteFile(WallpaperControllerImpl::GetCustomWallpaperDir(
+                       WallpaperControllerImpl::kSmallWallpaperSubDir)
                        .Append(wallpaper_files_id),
                    true /* recursive */);
-  base::DeleteFile(WallpaperController::GetCustomWallpaperDir(
-                       WallpaperController::kLargeWallpaperSubDir)
+  base::DeleteFile(WallpaperControllerImpl::GetCustomWallpaperDir(
+                       WallpaperControllerImpl::kLargeWallpaperSubDir)
                        .Append(wallpaper_files_id),
                    true /* recursive */);
   EnsureCustomWallpaperDirectories(wallpaper_files_id);
   const std::string file_name = original_path.BaseName().value();
   const base::FilePath small_wallpaper_path =
-      WallpaperController::GetCustomWallpaperPath(
-          WallpaperController::kSmallWallpaperSubDir, wallpaper_files_id,
+      WallpaperControllerImpl::GetCustomWallpaperPath(
+          WallpaperControllerImpl::kSmallWallpaperSubDir, wallpaper_files_id,
           file_name);
   const base::FilePath large_wallpaper_path =
-      WallpaperController::GetCustomWallpaperPath(
-          WallpaperController::kLargeWallpaperSubDir, wallpaper_files_id,
+      WallpaperControllerImpl::GetCustomWallpaperPath(
+          WallpaperControllerImpl::kLargeWallpaperSubDir, wallpaper_files_id,
           file_name);
 
   // Re-encode orginal file to jpeg format and saves the result in case that
@@ -364,28 +365,30 @@
          *active_user_type == user_manager::USER_TYPE_KIOSK_APP;
 }
 
+// Returns the currently active user session (at index 0).
+const UserSession* GetActiveUserSession() {
+  return Shell::Get()->session_controller()->GetUserSession(/*user index=*/0);
+}
+
 // Checks if |account_id| is the current active user.
 bool IsActiveUser(const AccountId& account_id) {
-  // The current active user has index 0.
-  const UserSession* const active_user_session =
-      Shell::Get()->session_controller()->GetUserSession(/*user index=*/0);
-  return active_user_session &&
-         active_user_session->user_info.account_id == account_id;
+  const UserSession* const session = GetActiveUserSession();
+  return session && session->user_info.account_id == account_id;
 }
 
 // Returns the file path of the wallpaper corresponding to |url| if it exists in
 // local file system, otherwise returns an empty file path.
 base::FilePath GetExistingOnlineWallpaperPath(const std::string& url) {
-  WallpaperController::WallpaperResolution resolution =
+  WallpaperControllerImpl::WallpaperResolution resolution =
       GetAppropriateResolution();
   base::FilePath wallpaper_path = GetOnlineWallpaperPath(url, resolution);
   if (base::PathExists(wallpaper_path))
     return wallpaper_path;
 
   // Falls back to the large wallpaper if the small one doesn't exist.
-  if (resolution == WallpaperController::WALLPAPER_RESOLUTION_SMALL) {
+  if (resolution == WallpaperControllerImpl::WALLPAPER_RESOLUTION_SMALL) {
     wallpaper_path = GetOnlineWallpaperPath(
-        url, WallpaperController::WALLPAPER_RESOLUTION_LARGE);
+        url, WallpaperControllerImpl::WALLPAPER_RESOLUTION_LARGE);
     if (base::PathExists(wallpaper_path))
       return wallpaper_path;
   }
@@ -404,18 +407,18 @@
   }
   ResizeAndSaveWallpaper(
       image,
-      GetOnlineWallpaperPath(url,
-                             WallpaperController::WALLPAPER_RESOLUTION_LARGE),
+      GetOnlineWallpaperPath(
+          url, WallpaperControllerImpl::WALLPAPER_RESOLUTION_LARGE),
       layout, image.width(), image.height());
   ResizeAndSaveWallpaper(
       image,
-      GetOnlineWallpaperPath(url,
-                             WallpaperController::WALLPAPER_RESOLUTION_SMALL),
+      GetOnlineWallpaperPath(
+          url, WallpaperControllerImpl::WALLPAPER_RESOLUTION_SMALL),
       WALLPAPER_LAYOUT_CENTER_CROPPED, kSmallWallpaperMaxWidth,
       kSmallWallpaperMaxHeight);
 }
 
-// Implementation of |WallpaperController::GetOfflineWallpaper|.
+// Implementation of |WallpaperControllerImpl::GetOfflineWallpaper|.
 std::vector<std::string> GetOfflineWallpaperListImpl() {
   DCHECK(!GlobalChromeOSWallpapersDir().empty());
   std::vector<std::string> url_list;
@@ -438,11 +441,11 @@
 
 }  // namespace
 
-const char WallpaperController::kSmallWallpaperSubDir[] = "small";
-const char WallpaperController::kLargeWallpaperSubDir[] = "large";
-const char WallpaperController::kOriginalWallpaperSubDir[] = "original";
+const char WallpaperControllerImpl::kSmallWallpaperSubDir[] = "small";
+const char WallpaperControllerImpl::kLargeWallpaperSubDir[] = "large";
+const char WallpaperControllerImpl::kOriginalWallpaperSubDir[] = "original";
 
-WallpaperController::WallpaperController(PrefService* local_state)
+WallpaperControllerImpl::WallpaperControllerImpl(PrefService* local_state)
     : locked_(false),
       wallpaper_mode_(WALLPAPER_NONE),
       color_profiles_(GetProminentColorProfiles()),
@@ -453,6 +456,8 @@
       scoped_session_observer_(this),
       local_state_(local_state),
       weak_factory_(this) {
+  DCHECK(!g_instance_);
+  g_instance_ = this;
   DCHECK(!color_profiles_.empty());
   prominent_colors_ =
       std::vector<SkColor>(color_profiles_.size(), kInvalidWallpaperColor);
@@ -460,7 +465,7 @@
   Shell::Get()->AddShellObserver(this);
 }
 
-WallpaperController::~WallpaperController() {
+WallpaperControllerImpl::~WallpaperControllerImpl() {
   if (current_wallpaper_)
     current_wallpaper_->RemoveObserver(this);
   if (color_calculator_)
@@ -468,17 +473,19 @@
   Shell::Get()->window_tree_host_manager()->RemoveObserver(this);
   Shell::Get()->RemoveShellObserver(this);
   weak_factory_.InvalidateWeakPtrs();
+  DCHECK_EQ(g_instance_, this);
+  g_instance_ = nullptr;
 }
 
 // static
-void WallpaperController::RegisterLocalStatePrefs(
+void WallpaperControllerImpl::RegisterLocalStatePrefs(
     PrefRegistrySimple* registry) {
   registry->RegisterDictionaryPref(prefs::kUserWallpaperInfo);
   registry->RegisterDictionaryPref(prefs::kWallpaperColors);
 }
 
 // static
-gfx::Size WallpaperController::GetMaxDisplaySizeInNative() {
+gfx::Size WallpaperControllerImpl::GetMaxDisplaySizeInNative() {
   // Return an empty size for test environments where the screen is null.
   if (!display::Screen::GetScreen())
     return gfx::Size();
@@ -502,7 +509,7 @@
 }
 
 // static
-base::FilePath WallpaperController::GetCustomWallpaperPath(
+base::FilePath WallpaperControllerImpl::GetCustomWallpaperPath(
     const std::string& sub_dir,
     const std::string& wallpaper_files_id,
     const std::string& file_name) {
@@ -511,21 +518,21 @@
 }
 
 // static
-base::FilePath WallpaperController::GetCustomWallpaperDir(
+base::FilePath WallpaperControllerImpl::GetCustomWallpaperDir(
     const std::string& sub_dir) {
   DCHECK(!GlobalChromeOSCustomWallpapersDir().empty());
   return GlobalChromeOSCustomWallpapersDir().Append(sub_dir);
 }
 
 // static
-void WallpaperController::SetWallpaperFromPath(
+void WallpaperControllerImpl::SetWallpaperFromPath(
     const AccountId& account_id,
     const user_manager::UserType& user_type,
     const WallpaperInfo& info,
     const base::FilePath& wallpaper_path,
     bool show_wallpaper,
     const scoped_refptr<base::SingleThreadTaskRunner>& reply_task_runner,
-    base::WeakPtr<WallpaperController> weak_ptr) {
+    base::WeakPtr<WallpaperControllerImpl> weak_ptr) {
   base::FilePath valid_path = wallpaper_path;
   if (!base::PathExists(valid_path)) {
     // Falls back to the original file if the file with correct resolution does
@@ -540,51 +547,37 @@
                << " doesn't exist. Falls back to default wallpaper.";
     reply_task_runner->PostTask(
         FROM_HERE,
-        base::BindOnce(&WallpaperController::SetDefaultWallpaperImpl, weak_ptr,
-                       account_id, user_type, show_wallpaper));
+        base::BindOnce(&WallpaperControllerImpl::SetDefaultWallpaperImpl,
+                       weak_ptr, account_id, user_type, show_wallpaper));
   } else {
     reply_task_runner->PostTask(
-        FROM_HERE, base::BindOnce(&WallpaperController::StartDecodeFromPath,
+        FROM_HERE, base::BindOnce(&WallpaperControllerImpl::StartDecodeFromPath,
                                   weak_ptr, account_id, user_type, valid_path,
                                   info, show_wallpaper));
   }
 }
 
-void WallpaperController::BindRequest(
-    mojom::WallpaperControllerRequest request) {
-  bindings_.AddBinding(this, std::move(request));
-}
-
-void WallpaperController::AddObserver(WallpaperControllerObserver* observer) {
-  observers_.AddObserver(observer);
-}
-
-void WallpaperController::RemoveObserver(
-    WallpaperControllerObserver* observer) {
-  observers_.RemoveObserver(observer);
-}
-
-SkColor WallpaperController::GetProminentColor(
+SkColor WallpaperControllerImpl::GetProminentColor(
     ColorProfile color_profile) const {
   ColorProfileType type = GetColorProfileType(color_profile);
   return prominent_colors_[static_cast<int>(type)];
 }
 
-gfx::ImageSkia WallpaperController::GetWallpaper() const {
+gfx::ImageSkia WallpaperControllerImpl::GetWallpaper() const {
   return current_wallpaper_ ? current_wallpaper_->image() : gfx::ImageSkia();
 }
 
-WallpaperLayout WallpaperController::GetWallpaperLayout() const {
+WallpaperLayout WallpaperControllerImpl::GetWallpaperLayout() const {
   return current_wallpaper_ ? current_wallpaper_->wallpaper_info().layout
                             : NUM_WALLPAPER_LAYOUT;
 }
 
-WallpaperType WallpaperController::GetWallpaperType() const {
+WallpaperType WallpaperControllerImpl::GetWallpaperType() const {
   return current_wallpaper_ ? current_wallpaper_->wallpaper_info().type
                             : WALLPAPER_TYPE_COUNT;
 }
 
-bool WallpaperController::ShouldShowInitialAnimation() {
+bool WallpaperControllerImpl::ShouldShowInitialAnimation() {
   // The slower initial animation is only applicable if:
   // 1) It's the first run after system boot, not after user sign-out.
   if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
@@ -605,7 +598,7 @@
   return true;
 }
 
-void WallpaperController::OnWallpaperAnimationFinished() {
+void WallpaperControllerImpl::OnWallpaperAnimationFinished() {
   // TODO(crbug.com/875128): Remove this after web-ui login code is completely
   // removed.
   if (wallpaper_controller_client_ && is_first_wallpaper_) {
@@ -613,19 +606,19 @@
   }
 }
 
-bool WallpaperController::CanOpenWallpaperPicker() {
-  return ShouldShowWallpaperSettingImpl() &&
-         !IsActiveUserWallpaperControlledByPolicyImpl();
+bool WallpaperControllerImpl::CanOpenWallpaperPicker() {
+  return ShouldShowWallpaperSetting() &&
+         !IsActiveUserWallpaperControlledByPolicy();
 }
 
-bool WallpaperController::HasShownAnyWallpaper() const {
+bool WallpaperControllerImpl::HasShownAnyWallpaper() const {
   return !!current_wallpaper_;
 }
 
-void WallpaperController::ShowWallpaperImage(const gfx::ImageSkia& image,
-                                             WallpaperInfo info,
-                                             bool preview_mode,
-                                             bool always_on_top) {
+void WallpaperControllerImpl::ShowWallpaperImage(const gfx::ImageSkia& image,
+                                                 WallpaperInfo info,
+                                                 bool preview_mode,
+                                                 bool always_on_top) {
   // Prevent showing other wallpapers if there is an always-on-top wallpaper.
   if (is_always_on_top_wallpaper_ && !always_on_top)
     return;
@@ -672,23 +665,22 @@
     for (auto& observer : observers_)
       observer.OnFirstWallpaperShown();
   }
-  mojo_observers_.ForAllPtrs([this](mojom::WallpaperObserver* observer) {
-    observer->OnWallpaperChanged(current_wallpaper_->original_image_id());
-  });
+  for (auto& observer : observers_)
+    observer.OnWallpaperChanged();
 
   wallpaper_mode_ = WALLPAPER_IMAGE;
   InstallDesktopControllerForAllWindows();
   ++wallpaper_count_for_testing_;
 }
 
-bool WallpaperController::IsPolicyControlled(const AccountId& account_id,
-                                             bool is_ephemeral) const {
+bool WallpaperControllerImpl::IsPolicyControlled(const AccountId& account_id,
+                                                 bool is_ephemeral) const {
   WallpaperInfo info;
   return GetUserWallpaperInfo(account_id, &info, is_ephemeral) &&
          info.type == POLICY;
 }
 
-void WallpaperController::UpdateWallpaperBlur(bool blur) {
+void WallpaperControllerImpl::UpdateWallpaperBlur(bool blur) {
   bool needs_blur = blur && IsBlurAllowed();
   if (needs_blur == is_wallpaper_blurred_)
     return;
@@ -701,12 +693,9 @@
   is_wallpaper_blurred_ = needs_blur;
   for (auto& observer : observers_)
     observer.OnWallpaperBlurChanged();
-  mojo_observers_.ForAllPtrs([this](mojom::WallpaperObserver* observer) {
-    observer->OnWallpaperBlurChanged(is_wallpaper_blurred_);
-  });
 }
 
-bool WallpaperController::ShouldApplyDimming() const {
+bool WallpaperControllerImpl::ShouldApplyDimming() const {
   // Dim the wallpaper in a blocked user session or in tablet mode unless during
   // wallpaper preview.
   const bool should_dim =
@@ -718,17 +707,17 @@
   return should_dim && !IsOneShotWallpaper();
 }
 
-bool WallpaperController::IsBlurAllowed() const {
+bool WallpaperControllerImpl::IsBlurAllowed() const {
   return !IsDevicePolicyWallpaper() && !IsOneShotWallpaper();
 }
 
-bool WallpaperController::IsWallpaperBlurred() const {
+bool WallpaperControllerImpl::IsWallpaperBlurred() const {
   return is_wallpaper_blurred_;
 }
 
-bool WallpaperController::SetUserWallpaperInfo(const AccountId& account_id,
-                                               const WallpaperInfo& info,
-                                               bool is_ephemeral) {
+bool WallpaperControllerImpl::SetUserWallpaperInfo(const AccountId& account_id,
+                                                   const WallpaperInfo& info,
+                                                   bool is_ephemeral) {
   if (is_ephemeral) {
     ephemeral_users_wallpaper_info_[account_id] = info;
     return true;
@@ -760,9 +749,9 @@
   return true;
 }
 
-bool WallpaperController::GetUserWallpaperInfo(const AccountId& account_id,
-                                               WallpaperInfo* info,
-                                               bool is_ephemeral) const {
+bool WallpaperControllerImpl::GetUserWallpaperInfo(const AccountId& account_id,
+                                                   WallpaperInfo* info,
+                                                   bool is_ephemeral) const {
   if (is_ephemeral) {
     // Ephemeral users do not save anything to local state. Return true if the
     // info can be found in the map, otherwise return false.
@@ -807,8 +796,8 @@
   return true;
 }
 
-bool WallpaperController::GetWallpaperFromCache(const AccountId& account_id,
-                                                gfx::ImageSkia* image) {
+bool WallpaperControllerImpl::GetWallpaperFromCache(const AccountId& account_id,
+                                                    gfx::ImageSkia* image) {
   CustomWallpaperMap::const_iterator it = wallpaper_cache_map_.find(account_id);
   if (it != wallpaper_cache_map_.end() && !it->second.second.isNull()) {
     *image = it->second.second;
@@ -817,8 +806,8 @@
   return false;
 }
 
-bool WallpaperController::GetPathFromCache(const AccountId& account_id,
-                                           base::FilePath* path) {
+bool WallpaperControllerImpl::GetPathFromCache(const AccountId& account_id,
+                                               base::FilePath* path) {
   CustomWallpaperMap::const_iterator it = wallpaper_cache_map_.find(account_id);
   if (it != wallpaper_cache_map_.end()) {
     *path = it->second.first;
@@ -827,7 +816,7 @@
   return false;
 }
 
-void WallpaperController::AddFirstWallpaperAnimationEndCallback(
+void WallpaperControllerImpl::AddFirstWallpaperAnimationEndCallback(
     base::OnceClosure callback,
     aura::Window* window) {
   WallpaperWidgetController* wallpaper_widget_controller =
@@ -841,57 +830,58 @@
   }
 }
 
-void WallpaperController::StartDecodeFromPath(
+void WallpaperControllerImpl::StartDecodeFromPath(
     const AccountId& account_id,
     const user_manager::UserType& user_type,
     const base::FilePath& wallpaper_path,
     const WallpaperInfo& info,
     bool show_wallpaper) {
   ReadAndDecodeWallpaper(
-      base::BindOnce(&WallpaperController::OnWallpaperDecoded,
+      base::BindOnce(&WallpaperControllerImpl::OnWallpaperDecoded,
                      weak_factory_.GetWeakPtr(), account_id, user_type,
                      wallpaper_path, info, show_wallpaper),
       sequenced_task_runner_, wallpaper_path);
 }
 
-void WallpaperController::Init(
-    mojom::WallpaperControllerClientPtr client,
+void WallpaperControllerImpl::Init(
+    WallpaperControllerClient* client,
     const base::FilePath& user_data_path,
     const base::FilePath& chromeos_wallpapers_path,
     const base::FilePath& chromeos_custom_wallpapers_path,
     const base::FilePath& device_policy_wallpaper_path) {
-  DCHECK(!wallpaper_controller_client_.get());
-  wallpaper_controller_client_ = std::move(client);
-
+  DCHECK(!wallpaper_controller_client_);
   DCHECK(local_state_);
-  wallpaper_controller_client_->OnReadyToSetWallpaper();
+  wallpaper_controller_client_ = client;
 
   SetGlobalUserDataDir(user_data_path);
   SetGlobalChromeOSWallpapersDir(chromeos_wallpapers_path);
   SetGlobalChromeOSCustomWallpapersDir(chromeos_custom_wallpapers_path);
   SetDevicePolicyWallpaperPath(device_policy_wallpaper_path);
+
+  wallpaper_controller_client_->OnReadyToSetWallpaper();
 }
 
-void WallpaperController::SetCustomWallpaper(
-    mojom::WallpaperUserInfoPtr user_info,
+void WallpaperControllerImpl::SetCustomWallpaper(
+    const WallpaperUserInfo& user_info,
     const std::string& wallpaper_files_id,
     const std::string& file_name,
     WallpaperLayout layout,
     const gfx::ImageSkia& image,
     bool preview_mode) {
   DCHECK(Shell::Get()->session_controller()->IsActiveUserSessionStarted());
-  if (!CanSetUserWallpaper(user_info->account_id, user_info->is_ephemeral))
+  if (!CanSetUserWallpaper(user_info.account_id, user_info.is_ephemeral))
     return;
 
-  const bool is_active_user = IsActiveUser(user_info->account_id);
+  const bool is_active_user = IsActiveUser(user_info.account_id);
   if (preview_mode) {
     DCHECK(is_active_user);
-    confirm_preview_wallpaper_callback_ = base::BindOnce(
-        &WallpaperController::SaveAndSetWallpaper, weak_factory_.GetWeakPtr(),
-        std::move(user_info), wallpaper_files_id, file_name, CUSTOMIZED, layout,
-        /*show_wallpaper=*/false, image);
+    confirm_preview_wallpaper_callback_ =
+        base::BindOnce(&WallpaperControllerImpl::SaveAndSetWallpaper,
+                       weak_factory_.GetWeakPtr(), user_info,
+                       wallpaper_files_id, file_name, CUSTOMIZED, layout,
+                       /*show_wallpaper=*/false, image);
     reload_preview_wallpaper_callback_ =
-        base::BindRepeating(&WallpaperController::ShowWallpaperImage,
+        base::BindRepeating(&WallpaperControllerImpl::ShowWallpaperImage,
                             weak_factory_.GetWeakPtr(), image,
                             WallpaperInfo{std::string(), layout, CUSTOMIZED,
                                           base::Time::Now().LocalMidnight()},
@@ -899,49 +889,46 @@
     // Show the preview wallpaper.
     reload_preview_wallpaper_callback_.Run();
   } else {
-    SaveAndSetWallpaper(std::move(user_info), wallpaper_files_id, file_name,
-                        CUSTOMIZED, layout, /*show_wallpaper=*/is_active_user,
-                        image);
+    SaveAndSetWallpaper(user_info, wallpaper_files_id, file_name, CUSTOMIZED,
+                        layout, /*show_wallpaper=*/is_active_user, image);
   }
 }
 
-void WallpaperController::SetOnlineWallpaperIfExists(
-    mojom::WallpaperUserInfoPtr user_info,
+void WallpaperControllerImpl::SetOnlineWallpaperIfExists(
+    const WallpaperUserInfo& user_info,
     const std::string& url,
     WallpaperLayout layout,
     bool preview_mode,
     SetOnlineWallpaperIfExistsCallback callback) {
   DCHECK(Shell::Get()->session_controller()->IsActiveUserSessionStarted());
-  DCHECK(CanSetUserWallpaper(user_info->account_id, user_info->is_ephemeral));
+  DCHECK(CanSetUserWallpaper(user_info.account_id, user_info.is_ephemeral));
 
-  const OnlineWallpaperParams params = {user_info->account_id,
-                                        user_info->is_ephemeral, url, layout,
-                                        preview_mode};
+  const OnlineWallpaperParams params = {
+      user_info.account_id, user_info.is_ephemeral, url, layout, preview_mode};
   base::PostTaskAndReplyWithResult(
       sequenced_task_runner_.get(), FROM_HERE,
       base::BindOnce(&GetExistingOnlineWallpaperPath, url),
-      base::BindOnce(&WallpaperController::SetOnlineWallpaperFromPath,
+      base::BindOnce(&WallpaperControllerImpl::SetOnlineWallpaperFromPath,
                      weak_factory_.GetWeakPtr(), std::move(callback), params));
 }
 
-void WallpaperController::SetOnlineWallpaperFromData(
-    mojom::WallpaperUserInfoPtr user_info,
+void WallpaperControllerImpl::SetOnlineWallpaperFromData(
+    const WallpaperUserInfo& user_info,
     const std::string& image_data,
     const std::string& url,
     WallpaperLayout layout,
     bool preview_mode,
     SetOnlineWallpaperFromDataCallback callback) {
   if (!Shell::Get()->session_controller()->IsActiveUserSessionStarted() ||
-      !CanSetUserWallpaper(user_info->account_id, user_info->is_ephemeral)) {
+      !CanSetUserWallpaper(user_info.account_id, user_info.is_ephemeral)) {
     std::move(callback).Run(/*success=*/false);
     return;
   }
 
-  const OnlineWallpaperParams params = {user_info->account_id,
-                                        user_info->is_ephemeral, url, layout,
-                                        preview_mode};
+  const OnlineWallpaperParams params = {
+      user_info.account_id, user_info.is_ephemeral, url, layout, preview_mode};
   LoadedCallback decoded_callback =
-      base::BindOnce(&WallpaperController::OnOnlineWallpaperDecoded,
+      base::BindOnce(&WallpaperControllerImpl::OnOnlineWallpaperDecoded,
                      weak_factory_.GetWeakPtr(), params, /*save_file=*/true,
                      std::move(callback));
   if (bypass_decode_for_testing_) {
@@ -957,27 +944,26 @@
                   std::move(decoded_callback));
 }
 
-void WallpaperController::SetDefaultWallpaper(
-    mojom::WallpaperUserInfoPtr user_info,
+void WallpaperControllerImpl::SetDefaultWallpaper(
+    const WallpaperUserInfo& user_info,
     const std::string& wallpaper_files_id,
     bool show_wallpaper) {
-  if (!CanSetUserWallpaper(user_info->account_id, user_info->is_ephemeral))
+  if (!CanSetUserWallpaper(user_info.account_id, user_info.is_ephemeral))
     return;
 
-  const AccountId account_id = user_info->account_id;
-  const bool is_ephemeral = user_info->is_ephemeral;
-  const user_manager::UserType type = user_info->type;
-
-  RemoveUserWallpaper(std::move(user_info), wallpaper_files_id);
-  if (!InitializeUserWallpaperInfo(account_id, is_ephemeral)) {
+  RemoveUserWallpaper(user_info, wallpaper_files_id);
+  if (!InitializeUserWallpaperInfo(user_info.account_id,
+                                   user_info.is_ephemeral)) {
     LOG(ERROR) << "Initializing user wallpaper info fails. This should never "
                   "happen except in tests.";
   }
-  if (show_wallpaper)
-    SetDefaultWallpaperImpl(account_id, type, /*show_wallpaper=*/true);
+  if (show_wallpaper) {
+    SetDefaultWallpaperImpl(user_info.account_id, user_info.type,
+                            /*show_wallpaper=*/true);
+  }
 }
 
-void WallpaperController::SetCustomizedDefaultWallpaperPaths(
+void WallpaperControllerImpl::SetCustomizedDefaultWallpaperPaths(
     const base::FilePath& customized_default_small_path,
     const base::FilePath& customized_default_large_path) {
   customized_default_small_path_ = customized_default_small_path;
@@ -994,8 +980,8 @@
                           show_wallpaper);
 }
 
-void WallpaperController::SetPolicyWallpaper(
-    mojom::WallpaperUserInfoPtr user_info,
+void WallpaperControllerImpl::SetPolicyWallpaper(
+    const WallpaperUserInfo& user_info,
     const std::string& wallpaper_files_id,
     const std::string& data) {
   // There is no visible wallpaper in kiosk mode.
@@ -1006,9 +992,9 @@
   const bool show_wallpaper =
       Shell::Get()->session_controller()->IsActiveUserSessionStarted();
   LoadedCallback callback = base::BindOnce(
-      &WallpaperController::SaveAndSetWallpaper, weak_factory_.GetWeakPtr(),
-      base::Passed(&user_info), wallpaper_files_id, kPolicyWallpaperFile,
-      POLICY, WALLPAPER_LAYOUT_CENTER_CROPPED, show_wallpaper);
+      &WallpaperControllerImpl::SaveAndSetWallpaper, weak_factory_.GetWeakPtr(),
+      user_info, wallpaper_files_id, kPolicyWallpaperFile, POLICY,
+      WALLPAPER_LAYOUT_CENTER_CROPPED, show_wallpaper);
 
   if (bypass_decode_for_testing_) {
     std::move(callback).Run(CreateSolidColorWallpaper(kDefaultWallpaperColor));
@@ -1020,7 +1006,7 @@
                   std::move(callback));
 }
 
-void WallpaperController::SetDevicePolicyWallpaperPath(
+void WallpaperControllerImpl::SetDevicePolicyWallpaperPath(
     const base::FilePath& device_policy_wallpaper_path) {
   const bool was_device_policy_wallpaper_enforced =
       !device_policy_wallpaper_path_.empty();
@@ -1038,27 +1024,24 @@
   }
 }
 
-void WallpaperController::SetThirdPartyWallpaper(
-    mojom::WallpaperUserInfoPtr user_info,
+bool WallpaperControllerImpl::SetThirdPartyWallpaper(
+    const WallpaperUserInfo& user_info,
     const std::string& wallpaper_files_id,
     const std::string& file_name,
     WallpaperLayout layout,
-    const gfx::ImageSkia& image,
-    SetThirdPartyWallpaperCallback callback) {
-  const uint32_t image_id = WallpaperResizer::GetImageId(image);
+    const gfx::ImageSkia& image) {
   bool allowed_to_set_wallpaper =
-      CanSetUserWallpaper(user_info->account_id, user_info->is_ephemeral);
-  bool allowed_to_show_wallpaper = IsActiveUser(user_info->account_id);
-  std::move(callback).Run(allowed_to_set_wallpaper && allowed_to_show_wallpaper,
-                          image_id);
+      CanSetUserWallpaper(user_info.account_id, user_info.is_ephemeral);
+  bool allowed_to_show_wallpaper = IsActiveUser(user_info.account_id);
 
   if (allowed_to_set_wallpaper) {
-    SaveAndSetWallpaper(std::move(user_info), wallpaper_files_id, file_name,
-                        CUSTOMIZED, layout, allowed_to_show_wallpaper, image);
+    SaveAndSetWallpaper(user_info, wallpaper_files_id, file_name, CUSTOMIZED,
+                        layout, allowed_to_show_wallpaper, image);
   }
+  return allowed_to_set_wallpaper && allowed_to_show_wallpaper;
 }
 
-void WallpaperController::ConfirmPreviewWallpaper() {
+void WallpaperControllerImpl::ConfirmPreviewWallpaper() {
   if (!confirm_preview_wallpaper_callback_) {
     DCHECK(!reload_preview_wallpaper_callback_);
     return;
@@ -1069,7 +1052,7 @@
     observer.OnWallpaperPreviewEnded();
 }
 
-void WallpaperController::CancelPreviewWallpaper() {
+void WallpaperControllerImpl::CancelPreviewWallpaper() {
   if (!confirm_preview_wallpaper_callback_) {
     DCHECK(!reload_preview_wallpaper_callback_);
     return;
@@ -1081,21 +1064,18 @@
     observer.OnWallpaperPreviewEnded();
 }
 
-void WallpaperController::UpdateCustomWallpaperLayout(
-    mojom::WallpaperUserInfoPtr user_info,
+void WallpaperControllerImpl::UpdateCustomWallpaperLayout(
+    const WallpaperUserInfo& user_info,
     WallpaperLayout layout) {
   // This method has a very specific use case: the user should be active and
   // have a custom wallpaper.
-  // The currently active user has index 0.
-  const UserSession* const active_user_session =
-      Shell::Get()->session_controller()->GetUserSession(/*user index=*/0);
-  if (!active_user_session ||
-      active_user_session->user_info.account_id != user_info->account_id) {
+  const UserSession* const session = GetActiveUserSession();
+  if (!session || session->user_info.account_id != user_info.account_id)
     return;
-  }
+
   WallpaperInfo info;
-  if (!GetUserWallpaperInfo(user_info->account_id, &info,
-                            user_info->is_ephemeral) ||
+  if (!GetUserWallpaperInfo(user_info.account_id, &info,
+                            user_info.is_ephemeral) ||
       info.type != CUSTOMIZED) {
     return;
   }
@@ -1103,21 +1083,20 @@
     return;
 
   info.layout = layout;
-  if (!SetUserWallpaperInfo(user_info->account_id, info,
-                            user_info->is_ephemeral)) {
+  if (!SetUserWallpaperInfo(user_info.account_id, info,
+                            user_info.is_ephemeral)) {
     LOG(ERROR) << "Setting user wallpaper info fails. This should never happen "
                   "except in tests.";
   }
-  ShowUserWallpaper(std::move(user_info));
+  ShowUserWallpaper(user_info);
 }
 
-void WallpaperController::ShowUserWallpaper(
-    mojom::WallpaperUserInfoPtr user_info) {
-  current_user_ = std::move(user_info);
-  const user_manager::UserType user_type = current_user_->type;
+void WallpaperControllerImpl::ShowUserWallpaper(
+    const WallpaperUserInfo& user_info) {
+  current_user_ = user_info;
 
-  if (user_type == user_manager::USER_TYPE_KIOSK_APP ||
-      user_type == user_manager::USER_TYPE_ARC_KIOSK_APP) {
+  if (current_user_.type == user_manager::USER_TYPE_KIOSK_APP ||
+      current_user_.type == user_manager::USER_TYPE_ARC_KIOSK_APP) {
     return;
   }
 
@@ -1126,8 +1105,8 @@
     return;
   }
 
-  const AccountId account_id = current_user_->account_id;
-  const bool is_ephemeral = current_user_->is_ephemeral;
+  const AccountId account_id = current_user_.account_id;
+  const bool is_ephemeral = current_user_.is_ephemeral;
   WallpaperInfo info;
   if (!GetUserWallpaperInfo(account_id, &info, is_ephemeral)) {
     if (!InitializeUserWallpaperInfo(account_id, is_ephemeral))
@@ -1150,14 +1129,14 @@
   }
 
   if (info.type == DEFAULT) {
-    SetDefaultWallpaperImpl(account_id, current_user_->type,
+    SetDefaultWallpaperImpl(account_id, current_user_.type,
                             /*show_wallpaper=*/true);
     return;
   }
 
   if (info.type != CUSTOMIZED && info.type != POLICY && info.type != DEVICE) {
     // Load wallpaper according to WallpaperInfo.
-    SetWallpaperFromInfo(account_id, current_user_->type, info,
+    SetWallpaperFromInfo(account_id, current_user_.type, info,
                          /*show_wallpaper=*/true);
     return;
   }
@@ -1189,14 +1168,14 @@
 
   sequenced_task_runner_->PostTask(
       FROM_HERE,
-      base::BindOnce(&SetWallpaperFromPath, account_id, current_user_->type,
+      base::BindOnce(&SetWallpaperFromPath, account_id, current_user_.type,
                      info, wallpaper_path, /*show_wallpaper=*/true,
                      base::ThreadTaskRunnerHandle::Get(),
                      weak_factory_.GetWeakPtr()));
 }
 
-void WallpaperController::ShowSigninWallpaper() {
-  current_user_.reset();
+void WallpaperControllerImpl::ShowSigninWallpaper() {
+  current_user_ = WallpaperUserInfo();
   if (ShouldSetDevicePolicyWallpaper()) {
     SetDevicePolicyWallpaper();
   } else {
@@ -1205,7 +1184,8 @@
   }
 }
 
-void WallpaperController::ShowOneShotWallpaper(const gfx::ImageSkia& image) {
+void WallpaperControllerImpl::ShowOneShotWallpaper(
+    const gfx::ImageSkia& image) {
   const WallpaperInfo info = {
       std::string(), WallpaperLayout::WALLPAPER_LAYOUT_STRETCH,
       WallpaperType::ONE_SHOT, base::Time::Now().LocalMidnight()};
@@ -1213,19 +1193,19 @@
                      /*always_on_top=*/false);
 }
 
-void WallpaperController::ShowAlwaysOnTopWallpaper(
+void WallpaperControllerImpl::ShowAlwaysOnTopWallpaper(
     const base::FilePath& image_path) {
   is_always_on_top_wallpaper_ = true;
   const WallpaperInfo info = {
       std::string(), WallpaperLayout::WALLPAPER_LAYOUT_CENTER_CROPPED,
       WallpaperType::ONE_SHOT, base::Time::Now().LocalMidnight()};
   ReadAndDecodeWallpaper(
-      base::BindOnce(&WallpaperController::OnAlwaysOnTopWallpaperDecoded,
+      base::BindOnce(&WallpaperControllerImpl::OnAlwaysOnTopWallpaperDecoded,
                      weak_factory_.GetWeakPtr(), info),
       sequenced_task_runner_, image_path);
 }
 
-void WallpaperController::RemoveAlwaysOnTopWallpaper() {
+void WallpaperControllerImpl::RemoveAlwaysOnTopWallpaper() {
   if (!is_always_on_top_wallpaper_) {
     DCHECK(!reload_always_on_top_wallpaper_callback_);
     return;
@@ -1235,17 +1215,17 @@
   ReloadWallpaper(/*clear_cache=*/false);
 }
 
-void WallpaperController::RemoveUserWallpaper(
-    mojom::WallpaperUserInfoPtr user_info,
+void WallpaperControllerImpl::RemoveUserWallpaper(
+    const WallpaperUserInfo& user_info,
     const std::string& wallpaper_files_id) {
-  RemoveUserWallpaperInfo(user_info->account_id, user_info->is_ephemeral);
-  RemoveUserWallpaperImpl(user_info->account_id, wallpaper_files_id);
+  RemoveUserWallpaperInfo(user_info.account_id, user_info.is_ephemeral);
+  RemoveUserWallpaperImpl(user_info.account_id, wallpaper_files_id);
 }
 
-void WallpaperController::RemovePolicyWallpaper(
-    mojom::WallpaperUserInfoPtr user_info,
+void WallpaperControllerImpl::RemovePolicyWallpaper(
+    const WallpaperUserInfo& user_info,
     const std::string& wallpaper_files_id) {
-  if (!IsPolicyControlled(user_info->account_id, user_info->is_ephemeral))
+  if (!IsPolicyControlled(user_info.account_id, user_info.is_ephemeral))
     return;
 
   // Updates the screen only when the user has logged in.
@@ -1253,29 +1233,29 @@
       Shell::Get()->session_controller()->IsActiveUserSessionStarted();
   // Removes the wallpaper info so that the user is no longer policy controlled,
   // otherwise setting default wallpaper is not allowed.
-  RemoveUserWallpaperInfo(user_info->account_id, user_info->is_ephemeral);
-  SetDefaultWallpaper(std::move(user_info), wallpaper_files_id, show_wallpaper);
+  RemoveUserWallpaperInfo(user_info.account_id, user_info.is_ephemeral);
+  SetDefaultWallpaper(user_info, wallpaper_files_id, show_wallpaper);
 }
 
-void WallpaperController::GetOfflineWallpaperList(
+void WallpaperControllerImpl::GetOfflineWallpaperList(
     GetOfflineWallpaperListCallback callback) {
   base::PostTaskAndReplyWithResult(sequenced_task_runner_.get(), FROM_HERE,
                                    base::BindOnce(&GetOfflineWallpaperListImpl),
                                    std::move(callback));
 }
 
-void WallpaperController::SetAnimationDuration(
+void WallpaperControllerImpl::SetAnimationDuration(
     base::TimeDelta animation_duration) {
   animation_duration_ = animation_duration;
 }
 
-void WallpaperController::OpenWallpaperPickerIfAllowed() {
+void WallpaperControllerImpl::OpenWallpaperPickerIfAllowed() {
   if (wallpaper_controller_client_ && CanOpenWallpaperPicker()) {
     wallpaper_controller_client_->OpenWallpaperPicker();
   }
 }
 
-void WallpaperController::MinimizeInactiveWindows(
+void WallpaperControllerImpl::MinimizeInactiveWindows(
     const std::string& user_id_hash) {
   if (!window_state_manager_)
     window_state_manager_ = std::make_unique<WallpaperWindowStateManager>();
@@ -1283,7 +1263,7 @@
   window_state_manager_->MinimizeInactiveWindows(user_id_hash);
 }
 
-void WallpaperController::RestoreMinimizedWindows(
+void WallpaperControllerImpl::RestoreMinimizedWindows(
     const std::string& user_id_hash) {
   if (!window_state_manager_) {
     NOTREACHED() << "This should only be called after calling "
@@ -1293,50 +1273,62 @@
   window_state_manager_->RestoreMinimizedWindows(user_id_hash);
 }
 
-void WallpaperController::AddObserver(
-    mojom::WallpaperObserverAssociatedPtrInfo observer) {
-  mojom::WallpaperObserverAssociatedPtr observer_ptr;
-  observer_ptr.Bind(std::move(observer));
-  observer_ptr->OnWallpaperColorsChanged(prominent_colors_);
-  mojo_observers_.AddPtr(std::move(observer_ptr));
+void WallpaperControllerImpl::AddObserver(
+    WallpaperControllerObserver* observer) {
+  observers_.AddObserver(observer);
 }
 
-void WallpaperController::GetWallpaperImage(
-    GetWallpaperImageCallback callback) {
-  std::move(callback).Run(GetWallpaper());
+void WallpaperControllerImpl::RemoveObserver(
+    WallpaperControllerObserver* observer) {
+  observers_.RemoveObserver(observer);
 }
 
-void WallpaperController::GetWallpaperColors(
-    GetWallpaperColorsCallback callback) {
-  std::move(callback).Run(prominent_colors_);
+gfx::ImageSkia WallpaperControllerImpl::GetWallpaperImage() {
+  return GetWallpaper();
 }
 
-void WallpaperController::IsWallpaperBlurred(
-    IsWallpaperBlurredCallback callback) {
-  std::move(callback).Run(is_wallpaper_blurred_);
+const std::vector<SkColor>& WallpaperControllerImpl::GetWallpaperColors() {
+  return prominent_colors_;
 }
 
-void WallpaperController::IsActiveUserWallpaperControlledByPolicy(
-    IsActiveUserWallpaperControlledByPolicyCallback callback) {
-  std::move(callback).Run(IsActiveUserWallpaperControlledByPolicyImpl());
+bool WallpaperControllerImpl::IsWallpaperBlurred() {
+  return is_wallpaper_blurred_;
 }
 
-void WallpaperController::GetActiveUserWallpaperInfo(
-    GetActiveUserWallpaperInfoCallback callback) {
+bool WallpaperControllerImpl::IsActiveUserWallpaperControlledByPolicy() {
+  const UserSession* const active_user_session = GetActiveUserSession();
+  if (!active_user_session)
+    return false;
+  return IsPolicyControlled(active_user_session->user_info.account_id,
+                            active_user_session->user_info.is_ephemeral);
+}
+
+WallpaperInfo WallpaperControllerImpl::GetActiveUserWallpaperInfo() {
   WallpaperInfo info;
-  if (!GetActiveUserWallpaperInfoImpl(&info)) {
-    std::move(callback).Run(std::string(), ash::NUM_WALLPAPER_LAYOUT);
-    return;
+  const UserSession* const active_user_session = GetActiveUserSession();
+  if (!active_user_session ||
+      !GetUserWallpaperInfo(active_user_session->user_info.account_id, &info,
+                            active_user_session->user_info.is_ephemeral)) {
+    info.location = std::string();
+    info.layout = NUM_WALLPAPER_LAYOUT;
   }
-  std::move(callback).Run(info.location, info.layout);
+
+  return info;
 }
 
-void WallpaperController::ShouldShowWallpaperSetting(
-    ShouldShowWallpaperSettingCallback callback) {
-  std::move(callback).Run(ShouldShowWallpaperSettingImpl());
+bool WallpaperControllerImpl::ShouldShowWallpaperSetting() {
+  const UserSession* const active_user_session = GetActiveUserSession();
+  if (!active_user_session)
+    return false;
+
+  user_manager::UserType active_user_type = active_user_session->user_info.type;
+  return active_user_type == user_manager::USER_TYPE_REGULAR ||
+         active_user_type == user_manager::USER_TYPE_PUBLIC_ACCOUNT ||
+         active_user_type == user_manager::USER_TYPE_SUPERVISED ||
+         active_user_type == user_manager::USER_TYPE_CHILD;
 }
 
-void WallpaperController::OnDisplayConfigurationChanged() {
+void WallpaperControllerImpl::OnDisplayConfigurationChanged() {
   gfx::Size max_display_size = GetMaxDisplaySizeInNative();
   if (current_max_display_size_ == max_display_size)
     return;
@@ -1347,12 +1339,12 @@
     GetInternalDisplayCompositorLock();
     timer_.Start(
         FROM_HERE, wallpaper_reload_delay_,
-        base::BindRepeating(&WallpaperController::ReloadWallpaper,
+        base::BindRepeating(&WallpaperControllerImpl::ReloadWallpaper,
                             weak_factory_.GetWeakPtr(), /*clear_cache=*/false));
   }
 }
 
-void WallpaperController::OnRootWindowAdded(aura::Window* root_window) {
+void WallpaperControllerImpl::OnRootWindowAdded(aura::Window* root_window) {
   // The wallpaper hasn't been set yet.
   if (wallpaper_mode_ == WALLPAPER_NONE)
     return;
@@ -1368,20 +1360,20 @@
   InstallDesktopController(root_window);
 }
 
-void WallpaperController::OnShellInitialized() {
+void WallpaperControllerImpl::OnShellInitialized() {
   Shell::Get()->tablet_mode_controller()->AddObserver(this);
 }
 
-void WallpaperController::OnShellDestroying() {
+void WallpaperControllerImpl::OnShellDestroying() {
   Shell::Get()->tablet_mode_controller()->RemoveObserver(this);
 }
 
-void WallpaperController::OnWallpaperResized() {
+void WallpaperControllerImpl::OnWallpaperResized() {
   CalculateWallpaperColors();
   compositor_lock_.reset();
 }
 
-void WallpaperController::OnColorCalculationComplete() {
+void WallpaperControllerImpl::OnColorCalculationComplete() {
   const std::vector<SkColor> colors = color_calculator_->prominent_colors();
   color_calculator_.reset();
   // Use |WallpaperInfo::location| as the key for storing |prominent_colors_| in
@@ -1394,7 +1386,7 @@
   SetProminentColors(colors);
 }
 
-void WallpaperController::OnSessionStateChanged(
+void WallpaperControllerImpl::OnSessionStateChanged(
     session_manager::SessionState state) {
   // Replace the device policy wallpaper with a user wallpaper if necessary.
   if (IsDevicePolicyWallpaper() && !ShouldSetDevicePolicyWallpaper())
@@ -1421,19 +1413,19 @@
     MoveToLockedContainer();
 }
 
-void WallpaperController::OnTabletModeStarted() {
+void WallpaperControllerImpl::OnTabletModeStarted() {
   RepaintWallpaper();
 }
 
-void WallpaperController::OnTabletModeEnded() {
+void WallpaperControllerImpl::OnTabletModeEnded() {
   RepaintWallpaper();
 }
 
-void WallpaperController::CompositorLockTimedOut() {
+void WallpaperControllerImpl::CompositorLockTimedOut() {
   compositor_lock_.reset();
 }
 
-void WallpaperController::InitializePathsForTesting(
+void WallpaperControllerImpl::InitializePathsForTesting(
     const base::FilePath& user_data_path,
     const base::FilePath& chromeos_wallpapers_path,
     const base::FilePath& chromeos_custom_wallpapers_path) {
@@ -1442,30 +1434,25 @@
   SetGlobalChromeOSCustomWallpapersDir(chromeos_custom_wallpapers_path);
 }
 
-void WallpaperController::ShowDefaultWallpaperForTesting() {
+void WallpaperControllerImpl::ShowDefaultWallpaperForTesting() {
   SetDefaultWallpaperImpl(EmptyAccountId(), user_manager::USER_TYPE_REGULAR,
                           /*show_wallpaper=*/true);
 }
 
-void WallpaperController::CreateEmptyWallpaperForTesting() {
+void WallpaperControllerImpl::CreateEmptyWallpaperForTesting() {
   ResetProminentColors();
   current_wallpaper_.reset();
   wallpaper_mode_ = WALLPAPER_IMAGE;
   InstallDesktopControllerForAllWindows();
 }
 
-void WallpaperController::SetClientForTesting(
-    mojom::WallpaperControllerClientPtr client) {
-  wallpaper_controller_client_ = std::move(client);
+void WallpaperControllerImpl::SetClientForTesting(
+    WallpaperControllerClient* client) {
+  wallpaper_controller_client_ = client;
 }
 
-void WallpaperController::FlushForTesting() {
-  if (wallpaper_controller_client_)
-    wallpaper_controller_client_.FlushForTesting();
-  mojo_observers_.FlushForTesting();
-}
-
-void WallpaperController::InstallDesktopController(aura::Window* root_window) {
+void WallpaperControllerImpl::InstallDesktopController(
+    aura::Window* root_window) {
   DCHECK_EQ(WALLPAPER_IMAGE, wallpaper_mode_);
 
   const bool is_wallpaper_blurred =
@@ -1475,9 +1462,6 @@
     is_wallpaper_blurred_ = is_wallpaper_blurred;
     for (auto& observer : observers_)
       observer.OnWallpaperBlurChanged();
-    mojo_observers_.ForAllPtrs([this](mojom::WallpaperObserver* observer) {
-      observer->OnWallpaperBlurChanged(is_wallpaper_blurred_);
-    });
   }
 
   const int container_id = GetWallpaperContainerId(locked_);
@@ -1511,13 +1495,13 @@
                                                   current_wallpaper_view, blur);
 }
 
-void WallpaperController::InstallDesktopControllerForAllWindows() {
+void WallpaperControllerImpl::InstallDesktopControllerForAllWindows() {
   for (aura::Window* root : Shell::GetAllRootWindows())
     InstallDesktopController(root);
   current_max_display_size_ = GetMaxDisplaySizeInNative();
 }
 
-bool WallpaperController::ReparentWallpaper(int container) {
+bool WallpaperControllerImpl::ReparentWallpaper(int container) {
   bool moved = false;
   for (auto* root_window_controller : Shell::GetAllRootWindowControllers()) {
     if (root_window_controller->wallpaper_widget_controller()->Reparent(
@@ -1528,7 +1512,7 @@
   return moved;
 }
 
-int WallpaperController::GetWallpaperContainerId(bool locked) {
+int WallpaperControllerImpl::GetWallpaperContainerId(bool locked) {
   if (is_always_on_top_wallpaper_)
     return kShellWindowId_AlwaysOnTopWallpaperContainer;
 
@@ -1536,8 +1520,9 @@
                 : kShellWindowId_WallpaperContainer;
 }
 
-void WallpaperController::RemoveUserWallpaperInfo(const AccountId& account_id,
-                                                  bool is_ephemeral) {
+void WallpaperControllerImpl::RemoveUserWallpaperInfo(
+    const AccountId& account_id,
+    bool is_ephemeral) {
   if (wallpaper_cache_map_.find(account_id) != wallpaper_cache_map_.end())
     wallpaper_cache_map_.erase(account_id);
 
@@ -1555,7 +1540,7 @@
   wallpaper_colors_update->RemoveWithoutPathExpansion(info.location, nullptr);
 }
 
-void WallpaperController::RemoveUserWallpaperImpl(
+void WallpaperControllerImpl::RemoveUserWallpaperImpl(
     const AccountId& account_id,
     const std::string& wallpaper_files_id) {
   if (wallpaper_files_id.empty())
@@ -1582,7 +1567,7 @@
       base::BindOnce(&DeleteWallpaperInList, std::move(files_to_remove)));
 }
 
-void WallpaperController::SetDefaultWallpaperImpl(
+void WallpaperControllerImpl::SetDefaultWallpaperImpl(
     const AccountId& account_id,
     const user_manager::UserType& user_type,
     bool show_wallpaper) {
@@ -1636,15 +1621,15 @@
                               cached_default_wallpaper_.image);
   } else {
     ReadAndDecodeWallpaper(
-        base::BindOnce(&WallpaperController::OnDefaultWallpaperDecoded,
+        base::BindOnce(&WallpaperControllerImpl::OnDefaultWallpaperDecoded,
                        weak_factory_.GetWeakPtr(), file_path, layout,
                        show_wallpaper),
         sequenced_task_runner_, file_path);
   }
 }
 
-bool WallpaperController::CanSetUserWallpaper(const AccountId& account_id,
-                                              bool is_ephemeral) const {
+bool WallpaperControllerImpl::CanSetUserWallpaper(const AccountId& account_id,
+                                                  bool is_ephemeral) const {
   // There is no visible wallpaper in kiosk mode.
   if (IsInKioskMode())
     return false;
@@ -1654,7 +1639,7 @@
   return true;
 }
 
-bool WallpaperController::WallpaperIsAlreadyLoaded(
+bool WallpaperControllerImpl::WallpaperIsAlreadyLoaded(
     const gfx::ImageSkia& image,
     bool compare_layouts,
     WallpaperLayout layout) const {
@@ -1669,7 +1654,7 @@
          current_wallpaper_->original_image_id();
 }
 
-void WallpaperController::ReadAndDecodeWallpaper(
+void WallpaperControllerImpl::ReadAndDecodeWallpaper(
     LoadedCallback callback,
     scoped_refptr<base::SequencedTaskRunner> task_runner,
     const base::FilePath& file_path) {
@@ -1686,7 +1671,7 @@
                      base::Passed(base::WrapUnique(data))));
 }
 
-bool WallpaperController::InitializeUserWallpaperInfo(
+bool WallpaperControllerImpl::InitializeUserWallpaperInfo(
     const AccountId& account_id,
     bool is_ephemeral) {
   const WallpaperInfo info = {std::string(), WALLPAPER_LAYOUT_CENTER_CROPPED,
@@ -1694,7 +1679,7 @@
   return SetUserWallpaperInfo(account_id, info, is_ephemeral);
 }
 
-void WallpaperController::SetOnlineWallpaperFromPath(
+void WallpaperControllerImpl::SetOnlineWallpaperFromPath(
     SetOnlineWallpaperIfExistsCallback callback,
     const OnlineWallpaperParams& params,
     const base::FilePath& file_path) {
@@ -1702,14 +1687,14 @@
   std::move(callback).Run(file_exists);
   if (file_exists) {
     ReadAndDecodeWallpaper(
-        base::BindOnce(&WallpaperController::OnOnlineWallpaperDecoded,
+        base::BindOnce(&WallpaperControllerImpl::OnOnlineWallpaperDecoded,
                        weak_factory_.GetWeakPtr(), params, /*save_file=*/false,
                        SetOnlineWallpaperFromDataCallback()),
         sequenced_task_runner_, file_path);
   }
 }
 
-void WallpaperController::OnOnlineWallpaperDecoded(
+void WallpaperControllerImpl::OnOnlineWallpaperDecoded(
     const OnlineWallpaperParams& params,
     bool save_file,
     SetOnlineWallpaperFromDataCallback callback,
@@ -1734,10 +1719,10 @@
   if (params.preview_mode) {
     DCHECK(is_active_user);
     confirm_preview_wallpaper_callback_ = base::BindOnce(
-        &WallpaperController::SetOnlineWallpaperImpl,
+        &WallpaperControllerImpl::SetOnlineWallpaperImpl,
         weak_factory_.GetWeakPtr(), params, image, /*show_wallpaper=*/false);
     reload_preview_wallpaper_callback_ =
-        base::BindRepeating(&WallpaperController::ShowWallpaperImage,
+        base::BindRepeating(&WallpaperControllerImpl::ShowWallpaperImage,
                             weak_factory_.GetWeakPtr(), image,
                             WallpaperInfo{params.url, params.layout, ONLINE,
                                           base::Time::Now().LocalMidnight()},
@@ -1749,7 +1734,7 @@
   }
 }
 
-void WallpaperController::SetOnlineWallpaperImpl(
+void WallpaperControllerImpl::SetOnlineWallpaperImpl(
     const OnlineWallpaperParams& params,
     const gfx::ImageSkia& image,
     bool show_wallpaper) {
@@ -1769,7 +1754,7 @@
       CustomWallpaperElement(base::FilePath(), image);
 }
 
-void WallpaperController::SetWallpaperFromInfo(
+void WallpaperControllerImpl::SetWallpaperFromInfo(
     const AccountId& account_id,
     const user_manager::UserType& user_type,
     const WallpaperInfo& info,
@@ -1806,7 +1791,7 @@
       return;
 
     ReadAndDecodeWallpaper(
-        base::BindOnce(&WallpaperController::OnWallpaperDecoded,
+        base::BindOnce(&WallpaperControllerImpl::OnWallpaperDecoded,
                        weak_factory_.GetWeakPtr(), account_id, user_type,
                        wallpaper_path, info, show_wallpaper),
         sequenced_task_runner_, wallpaper_path);
@@ -1820,14 +1805,14 @@
     wallpaper_path = GlobalUserDataDir().Append(info.location);
 
     ReadAndDecodeWallpaper(
-        base::BindOnce(&WallpaperController::OnWallpaperDecoded,
+        base::BindOnce(&WallpaperControllerImpl::OnWallpaperDecoded,
                        weak_factory_.GetWeakPtr(), account_id, user_type,
                        wallpaper_path, info, show_wallpaper),
         sequenced_task_runner_, wallpaper_path);
   }
 }
 
-void WallpaperController::OnDefaultWallpaperDecoded(
+void WallpaperControllerImpl::OnDefaultWallpaperDecoded(
     const base::FilePath& path,
     WallpaperLayout layout,
     bool show_wallpaper,
@@ -1850,8 +1835,8 @@
   }
 }
 
-void WallpaperController::SaveAndSetWallpaper(
-    mojom::WallpaperUserInfoPtr user_info,
+void WallpaperControllerImpl::SaveAndSetWallpaper(
+    const WallpaperUserInfo& user_info,
     const std::string& wallpaper_files_id,
     const std::string& file_name,
     WallpaperType type,
@@ -1872,20 +1857,20 @@
   // appropriate wallpaper resolution.
   WallpaperInfo info = {relative_path, layout, type,
                         base::Time::Now().LocalMidnight()};
-  if (!SetUserWallpaperInfo(user_info->account_id, info,
-                            user_info->is_ephemeral)) {
+  if (!SetUserWallpaperInfo(user_info.account_id, info,
+                            user_info.is_ephemeral)) {
     LOG(ERROR) << "Setting user wallpaper info fails. This should never happen "
                   "except in tests.";
   }
 
   base::FilePath wallpaper_path =
-      GetCustomWallpaperPath(WallpaperController::kOriginalWallpaperSubDir,
+      GetCustomWallpaperPath(WallpaperControllerImpl::kOriginalWallpaperSubDir,
                              wallpaper_files_id, file_name);
 
   const bool should_save_to_disk =
-      !user_info->is_ephemeral ||
+      !user_info.is_ephemeral ||
       (type == POLICY &&
-       user_info->type == user_manager::USER_TYPE_PUBLIC_ACCOUNT);
+       user_info.type == user_manager::USER_TYPE_PUBLIC_ACCOUNT);
 
   if (should_save_to_disk) {
     image.EnsureRepsForSupportedScales();
@@ -1906,11 +1891,11 @@
                        /*always_on_top=*/false);
   }
 
-  wallpaper_cache_map_[user_info->account_id] =
+  wallpaper_cache_map_[user_info.account_id] =
       CustomWallpaperElement(wallpaper_path, image);
 }
 
-void WallpaperController::OnWallpaperDecoded(
+void WallpaperControllerImpl::OnWallpaperDecoded(
     const AccountId& account_id,
     const user_manager::UserType& user_type,
     const base::FilePath& path,
@@ -1932,7 +1917,7 @@
   }
 }
 
-void WallpaperController::ReloadWallpaper(bool clear_cache) {
+void WallpaperControllerImpl::ReloadWallpaper(bool clear_cache) {
   current_wallpaper_.reset();
   if (clear_cache)
     wallpaper_cache_map_.clear();
@@ -1941,13 +1926,13 @@
     reload_always_on_top_wallpaper_callback_.Run();
   else if (reload_preview_wallpaper_callback_)
     reload_preview_wallpaper_callback_.Run();
-  else if (current_user_)
-    ShowUserWallpaper(std::move(current_user_));
+  else if (current_user_.account_id.is_valid())
+    ShowUserWallpaper(current_user_);
   else
     ShowSigninWallpaper();
 }
 
-void WallpaperController::SetProminentColors(
+void WallpaperControllerImpl::SetProminentColors(
     const std::vector<SkColor>& colors) {
   if (prominent_colors_ == colors)
     return;
@@ -1955,18 +1940,15 @@
   prominent_colors_ = colors;
   for (auto& observer : observers_)
     observer.OnWallpaperColorsChanged();
-  mojo_observers_.ForAllPtrs([this](mojom::WallpaperObserver* observer) {
-    observer->OnWallpaperColorsChanged(prominent_colors_);
-  });
 }
 
-void WallpaperController::ResetProminentColors() {
+void WallpaperControllerImpl::ResetProminentColors() {
   static const std::vector<SkColor> kInvalidColors(color_profiles_.size(),
                                                    kInvalidWallpaperColor);
   SetProminentColors(kInvalidColors);
 }
 
-void WallpaperController::CalculateWallpaperColors() {
+void WallpaperControllerImpl::CalculateWallpaperColors() {
   if (!current_wallpaper_)
     return;
 
@@ -2002,14 +1984,14 @@
   }
 }
 
-bool WallpaperController::ShouldCalculateColors() const {
+bool WallpaperControllerImpl::ShouldCalculateColors() const {
   gfx::ImageSkia image = GetWallpaper();
   return Shell::Get()->session_controller()->GetSessionState() ==
              session_manager::SessionState::ACTIVE &&
          !image.isNull();
 }
 
-void WallpaperController::CacheProminentColors(
+void WallpaperControllerImpl::CacheProminentColors(
     const std::vector<SkColor>& colors,
     const std::string& current_location) {
   if (!local_state_)
@@ -2023,7 +2005,7 @@
                                                    std::move(wallpaper_colors));
 }
 
-base::Optional<std::vector<SkColor>> WallpaperController::GetCachedColors(
+base::Optional<std::vector<SkColor>> WallpaperControllerImpl::GetCachedColors(
     const std::string& current_location) const {
   base::Optional<std::vector<SkColor>> cached_colors_out;
   const base::ListValue* prominent_colors = nullptr;
@@ -2041,7 +2023,7 @@
   return cached_colors_out;
 }
 
-void WallpaperController::OnAlwaysOnTopWallpaperDecoded(
+void WallpaperControllerImpl::OnAlwaysOnTopWallpaperDecoded(
     const WallpaperInfo& info,
     const gfx::ImageSkia& image) {
   // Do nothing if |RemoveAlwaysOnTopWallpaper| was called before decoding
@@ -2053,13 +2035,13 @@
     return;
   }
   reload_always_on_top_wallpaper_callback_ =
-      base::BindRepeating(&WallpaperController::ShowWallpaperImage,
+      base::BindRepeating(&WallpaperControllerImpl::ShowWallpaperImage,
                           weak_factory_.GetWeakPtr(), image, info,
                           /*preview_mode=*/false, /*always_on_top=*/true);
   reload_always_on_top_wallpaper_callback_.Run();
 }
 
-bool WallpaperController::MoveToLockedContainer() {
+bool WallpaperControllerImpl::MoveToLockedContainer() {
   if (locked_)
     return false;
 
@@ -2067,7 +2049,7 @@
   return ReparentWallpaper(GetWallpaperContainerId(true));
 }
 
-bool WallpaperController::MoveToUnlockedContainer() {
+bool WallpaperControllerImpl::MoveToUnlockedContainer() {
   if (!locked_)
     return false;
 
@@ -2075,17 +2057,17 @@
   return ReparentWallpaper(GetWallpaperContainerId(false));
 }
 
-bool WallpaperController::IsDevicePolicyWallpaper() const {
+bool WallpaperControllerImpl::IsDevicePolicyWallpaper() const {
   return current_wallpaper_ &&
          current_wallpaper_->wallpaper_info().type == WallpaperType::DEVICE;
 }
 
-bool WallpaperController::IsOneShotWallpaper() const {
+bool WallpaperControllerImpl::IsOneShotWallpaper() const {
   return current_wallpaper_ &&
          current_wallpaper_->wallpaper_info().type == WallpaperType::ONE_SHOT;
 }
 
-bool WallpaperController::ShouldSetDevicePolicyWallpaper() const {
+bool WallpaperControllerImpl::ShouldSetDevicePolicyWallpaper() const {
   // Only allow the device wallpaper if the policy is in effect for enterprise
   // managed devices.
   if (device_policy_wallpaper_path_.empty())
@@ -2096,15 +2078,16 @@
          session_manager::SessionState::LOGIN_PRIMARY;
 }
 
-void WallpaperController::SetDevicePolicyWallpaper() {
+void WallpaperControllerImpl::SetDevicePolicyWallpaper() {
   DCHECK(ShouldSetDevicePolicyWallpaper());
   ReadAndDecodeWallpaper(
-      base::BindRepeating(&WallpaperController::OnDevicePolicyWallpaperDecoded,
-                          weak_factory_.GetWeakPtr()),
+      base::BindRepeating(
+          &WallpaperControllerImpl::OnDevicePolicyWallpaperDecoded,
+          weak_factory_.GetWeakPtr()),
       sequenced_task_runner_.get(), device_policy_wallpaper_path_);
 }
 
-void WallpaperController::OnDevicePolicyWallpaperDecoded(
+void WallpaperControllerImpl::OnDevicePolicyWallpaperDecoded(
     const gfx::ImageSkia& image) {
   // It might be possible that the device policy controlled wallpaper finishes
   // decoding after the user logs in. In this case do nothing.
@@ -2125,46 +2108,7 @@
   }
 }
 
-bool WallpaperController::IsActiveUserWallpaperControlledByPolicyImpl() const {
-  // The currently active user has index 0.
-  const UserSession* const active_user_session =
-      Shell::Get()->session_controller()->GetUserSession(/*user index=*/0);
-  if (!active_user_session)
-    return false;
-  return IsPolicyControlled(active_user_session->user_info.account_id,
-                            active_user_session->user_info.is_ephemeral);
-}
-
-bool WallpaperController::GetActiveUserWallpaperInfoImpl(
-    WallpaperInfo* info_out) const {
-  // The currently active user has index 0.
-  const UserSession* const active_user_session =
-      Shell::Get()->session_controller()->GetUserSession(/*user index=*/0);
-  if (!active_user_session)
-    return false;
-
-  if (!GetUserWallpaperInfo(active_user_session->user_info.account_id, info_out,
-                            active_user_session->user_info.is_ephemeral)) {
-    return false;
-  }
-  return true;
-}
-
-bool WallpaperController::ShouldShowWallpaperSettingImpl() const {
-  // The currently active user has index 0.
-  const UserSession* const active_user_session =
-      Shell::Get()->session_controller()->GetUserSession(/*user index=*/0);
-  if (!active_user_session)
-    return false;
-
-  user_manager::UserType active_user_type = active_user_session->user_info.type;
-  return active_user_type == user_manager::USER_TYPE_REGULAR ||
-         active_user_type == user_manager::USER_TYPE_PUBLIC_ACCOUNT ||
-         active_user_type == user_manager::USER_TYPE_SUPERVISED ||
-         active_user_type == user_manager::USER_TYPE_CHILD;
-}
-
-void WallpaperController::GetInternalDisplayCompositorLock() {
+void WallpaperControllerImpl::GetInternalDisplayCompositorLock() {
   if (!display::Display::HasInternalDisplay())
     return;
 
@@ -2177,7 +2121,7 @@
       this, kCompositorLockTimeout);
 }
 
-void WallpaperController::RepaintWallpaper() {
+void WallpaperControllerImpl::RepaintWallpaper() {
   for (auto* root_window_controller : Shell::GetAllRootWindowControllers()) {
     auto* wallpaper_view =
         root_window_controller->wallpaper_widget_controller()->wallpaper_view();
diff --git a/ash/wallpaper/wallpaper_controller.h b/ash/wallpaper/wallpaper_controller_impl.h
similarity index 86%
rename from ash/wallpaper/wallpaper_controller.h
rename to ash/wallpaper/wallpaper_controller_impl.h
index 1f31c1b9..c605894 100644
--- a/ash/wallpaper/wallpaper_controller.h
+++ b/ash/wallpaper/wallpaper_controller_impl.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 ASH_WALLPAPER_WALLPAPER_CONTROLLER_H_
-#define ASH_WALLPAPER_WALLPAPER_CONTROLLER_H_
+#ifndef ASH_WALLPAPER_WALLPAPER_CONTROLLER_IMPL_H_
+#define ASH_WALLPAPER_WALLPAPER_CONTROLLER_IMPL_H_
 
 #include <map>
 #include <memory>
@@ -13,11 +13,12 @@
 
 #include "ash/ash_export.h"
 #include "ash/display/window_tree_host_manager.h"
+#include "ash/public/cpp/wallpaper_controller.h"
+#include "ash/public/cpp/wallpaper_info.h"
 #include "ash/public/cpp/wallpaper_types.h"
-#include "ash/public/interfaces/wallpaper.mojom.h"
+#include "ash/public/cpp/wallpaper_user_info.h"
 #include "ash/session/session_observer.h"
 #include "ash/shell_observer.h"
-#include "ash/wallpaper/wallpaper_info.h"
 #include "ash/wallpaper/wallpaper_utils/wallpaper_color_calculator_observer.h"
 #include "ash/wallpaper/wallpaper_utils/wallpaper_resizer_observer.h"
 #include "ash/wm/tablet_mode/tablet_mode_observer.h"
@@ -26,8 +27,6 @@
 #include "base/observer_list.h"
 #include "base/timer/timer.h"
 #include "components/user_manager/user_type.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
-#include "mojo/public/cpp/bindings/interface_ptr_set.h"
 #include "ui/compositor/compositor_lock.h"
 #include "ui/gfx/image/image_skia.h"
 
@@ -44,7 +43,6 @@
 namespace ash {
 
 class WallpaperColorCalculator;
-class WallpaperControllerObserver;
 class WallpaperResizer;
 class WallpaperWindowStateManager;
 
@@ -63,14 +61,15 @@
 //   - Move wallpaper to locked container(s) when session state is not ACTIVE to
 //     hide the user desktop and move it to unlocked container when session
 //     state is ACTIVE;
-class ASH_EXPORT WallpaperController : public mojom::WallpaperController,
-                                       public WindowTreeHostManager::Observer,
-                                       public ShellObserver,
-                                       public WallpaperResizerObserver,
-                                       public WallpaperColorCalculatorObserver,
-                                       public SessionObserver,
-                                       public TabletModeObserver,
-                                       public ui::CompositorLockClient {
+class ASH_EXPORT WallpaperControllerImpl
+    : public WallpaperController,
+      public WindowTreeHostManager::Observer,
+      public ShellObserver,
+      public WallpaperResizerObserver,
+      public WallpaperColorCalculatorObserver,
+      public SessionObserver,
+      public TabletModeObserver,
+      public ui::CompositorLockClient {
  public:
   enum WallpaperResolution {
     WALLPAPER_RESOLUTION_LARGE,
@@ -82,8 +81,8 @@
   static const char kLargeWallpaperSubDir[];
   static const char kOriginalWallpaperSubDir[];
 
-  explicit WallpaperController(PrefService* local_state);
-  ~WallpaperController() override;
+  explicit WallpaperControllerImpl(PrefService* local_state);
+  ~WallpaperControllerImpl() override;
 
   static void RegisterLocalStatePrefs(PrefRegistrySimple* registry);
 
@@ -113,14 +112,7 @@
       const base::FilePath& wallpaper_path,
       bool show_wallpaper,
       const scoped_refptr<base::SingleThreadTaskRunner>& reply_task_runner,
-      base::WeakPtr<WallpaperController> weak_ptr);
-
-  // Binds the mojom::WallpaperController interface request to this object.
-  void BindRequest(mojom::WallpaperControllerRequest request);
-
-  // Add/Remove observers.
-  void AddObserver(WallpaperControllerObserver* observer);
-  void RemoveObserver(WallpaperControllerObserver* observer);
+      base::WeakPtr<WallpaperControllerImpl> weak_ptr);
 
   // Returns the prominent color based on |color_profile|.
   SkColor GetProminentColor(color_utils::ColorProfile color_profile) const;
@@ -218,60 +210,59 @@
                            const WallpaperInfo& info,
                            bool show_wallpaper);
 
-  // mojom::WallpaperController:
-  void Init(mojom::WallpaperControllerClientPtr client,
+  // WallpaperController:
+  void Init(WallpaperControllerClient* client,
             const base::FilePath& user_data_path,
             const base::FilePath& chromeos_wallpapers_path,
             const base::FilePath& chromeos_custom_wallpapers_path,
             const base::FilePath& device_policy_wallpaper_path) override;
-  void SetCustomWallpaper(mojom::WallpaperUserInfoPtr user_info,
+  void SetCustomWallpaper(const WallpaperUserInfo& user_info,
                           const std::string& wallpaper_files_id,
                           const std::string& file_name,
                           WallpaperLayout layout,
                           const gfx::ImageSkia& image,
                           bool preview_mode) override;
   void SetOnlineWallpaperIfExists(
-      mojom::WallpaperUserInfoPtr user_info,
+      const WallpaperUserInfo& user_info,
       const std::string& url,
       WallpaperLayout layout,
       bool preview_mode,
       SetOnlineWallpaperIfExistsCallback callback) override;
   void SetOnlineWallpaperFromData(
-      mojom::WallpaperUserInfoPtr user_info,
+      const WallpaperUserInfo& user_info,
       const std::string& image_data,
       const std::string& url,
       WallpaperLayout layout,
       bool preview_mode,
       SetOnlineWallpaperFromDataCallback callback) override;
-  void SetDefaultWallpaper(mojom::WallpaperUserInfoPtr user_info,
+  void SetDefaultWallpaper(const WallpaperUserInfo& user_info,
                            const std::string& wallpaper_files_id,
                            bool show_wallpaper) override;
   void SetCustomizedDefaultWallpaperPaths(
       const base::FilePath& customized_default_small_path,
       const base::FilePath& customized_default_large_path) override;
-  void SetPolicyWallpaper(mojom::WallpaperUserInfoPtr user_info,
+  void SetPolicyWallpaper(const WallpaperUserInfo& user_info,
                           const std::string& wallpaper_files_id,
                           const std::string& data) override;
   void SetDevicePolicyWallpaperPath(
       const base::FilePath& device_policy_wallpaper_path) override;
-  void SetThirdPartyWallpaper(mojom::WallpaperUserInfoPtr user_info,
+  bool SetThirdPartyWallpaper(const WallpaperUserInfo& user_info,
                               const std::string& wallpaper_files_id,
                               const std::string& file_name,
                               WallpaperLayout layout,
-                              const gfx::ImageSkia& image,
-                              SetThirdPartyWallpaperCallback callback) override;
+                              const gfx::ImageSkia& image) override;
   void ConfirmPreviewWallpaper() override;
   void CancelPreviewWallpaper() override;
-  void UpdateCustomWallpaperLayout(mojom::WallpaperUserInfoPtr user_info,
+  void UpdateCustomWallpaperLayout(const WallpaperUserInfo& user_info,
                                    WallpaperLayout layout) override;
-  void ShowUserWallpaper(mojom::WallpaperUserInfoPtr user_info) override;
+  void ShowUserWallpaper(const WallpaperUserInfo& user_info) override;
   void ShowSigninWallpaper() override;
   void ShowOneShotWallpaper(const gfx::ImageSkia& image) override;
   void ShowAlwaysOnTopWallpaper(const base::FilePath& image_path) override;
   void RemoveAlwaysOnTopWallpaper() override;
-  void RemoveUserWallpaper(mojom::WallpaperUserInfoPtr user_info,
+  void RemoveUserWallpaper(const WallpaperUserInfo& user_info,
                            const std::string& wallpaper_files_id) override;
-  void RemovePolicyWallpaper(mojom::WallpaperUserInfoPtr user_info,
+  void RemovePolicyWallpaper(const WallpaperUserInfo& user_info,
                              const std::string& wallpaper_files_id) override;
   void GetOfflineWallpaperList(
       GetOfflineWallpaperListCallback callback) override;
@@ -279,16 +270,14 @@
   void OpenWallpaperPickerIfAllowed() override;
   void MinimizeInactiveWindows(const std::string& user_id_hash) override;
   void RestoreMinimizedWindows(const std::string& user_id_hash) override;
-  void AddObserver(mojom::WallpaperObserverAssociatedPtrInfo observer) override;
-  void GetWallpaperImage(GetWallpaperImageCallback callback) override;
-  void GetWallpaperColors(GetWallpaperColorsCallback callback) override;
-  void IsWallpaperBlurred(IsWallpaperBlurredCallback callback) override;
-  void IsActiveUserWallpaperControlledByPolicy(
-      IsActiveUserWallpaperControlledByPolicyCallback callback) override;
-  void GetActiveUserWallpaperInfo(
-      GetActiveUserWallpaperInfoCallback callback) override;
-  void ShouldShowWallpaperSetting(
-      ShouldShowWallpaperSettingCallback callback) override;
+  void AddObserver(WallpaperControllerObserver* observer) override;
+  void RemoveObserver(WallpaperControllerObserver* observer) override;
+  gfx::ImageSkia GetWallpaperImage() override;
+  const std::vector<SkColor>& GetWallpaperColors() override;
+  bool IsWallpaperBlurred() override;
+  bool IsActiveUserWallpaperControlledByPolicy() override;
+  WallpaperInfo GetActiveUserWallpaperInfo() override;
+  bool ShouldShowWallpaperSetting() override;
 
   // WindowTreeHostManager::Observer:
   void OnDisplayConfigurationChanged() override;
@@ -331,11 +320,8 @@
   // empty widget for those tests to prevent crashes.
   void CreateEmptyWallpaperForTesting();
 
-  // Sets a test client interface with empty file paths.
-  void SetClientForTesting(mojom::WallpaperControllerClientPtr client);
-
-  // Flushes the mojo message pipe to chrome.
-  void FlushForTesting();
+  // Sets a test client.
+  void SetClientForTesting(WallpaperControllerClient* client);
 
   void set_wallpaper_reload_no_delay_for_test() {
     wallpaper_reload_delay_ = base::TimeDelta::FromMilliseconds(0);
@@ -457,7 +443,7 @@
   // policy wallpaper for public accounts. Shows the wallpaper immediately if
   // |show_wallpaper| is true, otherwise only sets the wallpaper info and
   // updates the cache.
-  void SaveAndSetWallpaper(mojom::WallpaperUserInfoPtr user_info,
+  void SaveAndSetWallpaper(const WallpaperUserInfo& user_info,
                            const std::string& wallpaper_files_id,
                            const std::string& file_name,
                            WallpaperType type,
@@ -542,15 +528,6 @@
   // Called when the device policy controlled wallpaper has been decoded.
   void OnDevicePolicyWallpaperDecoded(const gfx::ImageSkia& image);
 
-  // Implementation of |IsActiveUserWallpaperControlledByPolicy|.
-  bool IsActiveUserWallpaperControlledByPolicyImpl() const;
-
-  // Implementation of |GetActiveUserWallpaperInfo|.
-  bool GetActiveUserWallpaperInfoImpl(WallpaperInfo* info_out) const;
-
-  // Implementation of |ShouldShowWallpaperSetting|.
-  bool ShouldShowWallpaperSettingImpl() const;
-
   // When wallpaper resizes, we can check which displays will be affected. For
   // simplicity, we only lock the compositor for the internal display.
   void GetInternalDisplayCompositorLock();
@@ -564,15 +541,10 @@
   WallpaperMode wallpaper_mode_;
 
   // Client interface in chrome browser.
-  mojom::WallpaperControllerClientPtr wallpaper_controller_client_;
-
-  // Bindings for the WallpaperController interface.
-  mojo::BindingSet<mojom::WallpaperController> bindings_;
+  WallpaperControllerClient* wallpaper_controller_client_ = nullptr;
 
   base::ObserverList<WallpaperControllerObserver>::Unchecked observers_;
 
-  mojo::AssociatedInterfacePtrSet<mojom::WallpaperObserver> mojo_observers_;
-
   std::unique_ptr<WallpaperResizer> current_wallpaper_;
 
   // Asynchronous task to extract colors from the wallpaper.
@@ -594,7 +566,7 @@
   std::map<AccountId, WallpaperInfo> ephemeral_users_wallpaper_info_;
 
   // Cached user info of the current user.
-  mojom::WallpaperUserInfoPtr current_user_;
+  WallpaperUserInfo current_user_;
 
   // Cached wallpapers of users.
   CustomWallpaperMap wallpaper_cache_map_;
@@ -661,15 +633,15 @@
   std::vector<base::FilePath> decode_requests_for_testing_;
 
   // PrefService provided by Shell when constructing this.
-  // Valid for the lifetime of ash::Shell which owns WallpaperController.
+  // Valid for the lifetime of ash::Shell which owns WallpaperControllerImpl.
   // May be null in tests.
   PrefService* local_state_ = nullptr;
 
-  base::WeakPtrFactory<WallpaperController> weak_factory_;
+  base::WeakPtrFactory<WallpaperControllerImpl> weak_factory_;
 
-  DISALLOW_COPY_AND_ASSIGN(WallpaperController);
+  DISALLOW_COPY_AND_ASSIGN(WallpaperControllerImpl);
 };
 
 }  // namespace ash
 
-#endif  // ASH_WALLPAPER_WALLPAPER_CONTROLLER_H_
+#endif  // ASH_WALLPAPER_WALLPAPER_CONTROLLER_IMPL_H_
diff --git a/ash/wallpaper/wallpaper_controller_observer.h b/ash/wallpaper/wallpaper_controller_observer.h
deleted file mode 100644
index c8c1199..0000000
--- a/ash/wallpaper/wallpaper_controller_observer.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_WALLPAPER_WALLPAPER_CONTROLLER_OBSERVER_H_
-#define ASH_WALLPAPER_WALLPAPER_CONTROLLER_OBSERVER_H_
-
-#include "ash/ash_export.h"
-
-namespace ash {
-
-class ASH_EXPORT WallpaperControllerObserver {
- public:
-  // Invoked when the colors extracted from the current wallpaper change.
-  virtual void OnWallpaperColorsChanged() {}
-
-  // Invoked when the blur state of the wallpaper changes.
-  virtual void OnWallpaperBlurChanged() {}
-
-  // Invoked when the wallpaper preview mode starts.
-  virtual void OnWallpaperPreviewStarted() {}
-
-  // Invoked when the wallpaper preview mode ends.
-  virtual void OnWallpaperPreviewEnded() {}
-
-  // Invoked when the first wallpaper is set. The first wallpaper is the one
-  // shown right after boot splash screen or after a session restart.
-  virtual void OnFirstWallpaperShown() {}
-
- protected:
-  virtual ~WallpaperControllerObserver() {}
-};
-
-}  // namespace ash
-
-#endif  // ASH_WALLPAPER_WALLPAPER_CONTROLLER_OBSERVER_H_
diff --git a/ash/wallpaper/wallpaper_controller_test_api.cc b/ash/wallpaper/wallpaper_controller_test_api.cc
index a60389f8..f0dc2de 100644
--- a/ash/wallpaper/wallpaper_controller_test_api.cc
+++ b/ash/wallpaper/wallpaper_controller_test_api.cc
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 #include "ash/wallpaper/wallpaper_controller_test_api.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "base/bind.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/color_utils.h"
@@ -26,7 +26,7 @@
 }  // namespace
 
 WallpaperControllerTestApi::WallpaperControllerTestApi(
-    WallpaperController* controller)
+    WallpaperControllerImpl* controller)
     : controller_(controller) {}
 
 WallpaperControllerTestApi::~WallpaperControllerTestApi() = default;
@@ -44,13 +44,13 @@
   // Preview mode is considered active when the two callbacks have non-empty
   // values. Their specific values don't matter for testing purpose.
   controller_->confirm_preview_wallpaper_callback_ =
-      base::BindOnce(&WallpaperController::SetWallpaperFromInfo,
+      base::BindOnce(&WallpaperControllerImpl::SetWallpaperFromInfo,
                      controller_->weak_factory_.GetWeakPtr(),
                      AccountId::FromUserEmail("user@test.com"),
                      user_manager::USER_TYPE_REGULAR, kTestWallpaperInfo,
                      /*show_wallpaper=*/true);
   controller_->reload_preview_wallpaper_callback_ = base::BindRepeating(
-      &WallpaperController::ShowWallpaperImage,
+      &WallpaperControllerImpl::ShowWallpaperImage,
       controller_->weak_factory_.GetWeakPtr(),
       CreateImageWithColor(SK_ColorBLUE), kTestWallpaperInfo,
       /*preview_mode=*/true, /*always_on_top=*/false);
diff --git a/ash/wallpaper/wallpaper_controller_test_api.h b/ash/wallpaper/wallpaper_controller_test_api.h
index 02f11f64..90aca5b 100644
--- a/ash/wallpaper/wallpaper_controller_test_api.h
+++ b/ash/wallpaper/wallpaper_controller_test_api.h
@@ -11,14 +11,14 @@
 
 namespace ash {
 
-class WallpaperController;
+class WallpaperControllerImpl;
 
 class ASH_EXPORT WallpaperControllerTestApi {
  public:
-  explicit WallpaperControllerTestApi(WallpaperController* controller);
+  explicit WallpaperControllerTestApi(WallpaperControllerImpl* controller);
   virtual ~WallpaperControllerTestApi();
 
-  // Creates and sets a new wallpaper that cause the prominent color of the
+  // Creates and sets a new wallpaper that causes the prominent color of the
   // |controller_| to be a valid (i.e. not kInvalidWallpaperColor) color. The
   // WallpaperControllerObservers should be notified as well. This assumes the
   // default DARK-MUTED luma-saturation ranges are in effect.
@@ -35,7 +35,7 @@
   void EndWallpaperPreview(bool confirm_preview_wallpaper);
 
  private:
-  WallpaperController* controller_;
+  WallpaperControllerImpl* controller_;
 
   DISALLOW_COPY_AND_ASSIGN(WallpaperControllerTestApi);
 };
diff --git a/ash/wallpaper/wallpaper_controller_unittest.cc b/ash/wallpaper/wallpaper_controller_unittest.cc
index f962980..c061a4e 100644
--- a/ash/wallpaper/wallpaper_controller_unittest.cc
+++ b/ash/wallpaper/wallpaper_controller_unittest.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 "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 
 #include <cmath>
 #include <cstdlib>
@@ -10,12 +10,12 @@
 #include "ash/public/cpp/ash_switches.h"
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/public/cpp/test/shell_test_api.h"
+#include "ash/public/cpp/wallpaper_controller_observer.h"
 #include "ash/root_window_controller.h"
 #include "ash/session/session_controller_impl.h"
 #include "ash/session/test_session_controller_client.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
-#include "ash/wallpaper/wallpaper_controller_observer.h"
 #include "ash/wallpaper/wallpaper_utils/wallpaper_resizer.h"
 #include "ash/wallpaper/wallpaper_view.h"
 #include "ash/wallpaper/wallpaper_widget_controller.h"
@@ -31,7 +31,6 @@
 #include "base/test/bind_test_util.h"
 #include "base/time/time_override.h"
 #include "chromeos/constants/chromeos_switches.h"
-#include "mojo/public/cpp/bindings/associated_binding.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/aura/window.h"
@@ -154,8 +153,9 @@
                                       const std::string& wallpaper_files_id,
                                       const std::string& file_name) {
   base::ScopedAllowBlockingForTesting allow_blocking;
-  base::FilePath wallpaper_path = WallpaperController::GetCustomWallpaperPath(
-      sub_dir, wallpaper_files_id, file_name);
+  base::FilePath wallpaper_path =
+      WallpaperControllerImpl::GetCustomWallpaperPath(
+          sub_dir, wallpaper_files_id, file_name);
   if (!base::DirectoryExists(wallpaper_path.DirName()))
     base::CreateDirectory(wallpaper_path.DirName());
 
@@ -166,16 +166,16 @@
   const std::string wallpaper_file_id = GetDummyFileId(account_id);
 
   base::FilePath small_wallpaper_dir =
-      WallpaperController::GetCustomWallpaperDir(
-          WallpaperController::kSmallWallpaperSubDir)
+      WallpaperControllerImpl::GetCustomWallpaperDir(
+          WallpaperControllerImpl::kSmallWallpaperSubDir)
           .Append(wallpaper_file_id);
   base::FilePath large_wallpaper_dir =
-      WallpaperController::GetCustomWallpaperDir(
-          WallpaperController::kLargeWallpaperSubDir)
+      WallpaperControllerImpl::GetCustomWallpaperDir(
+          WallpaperControllerImpl::kLargeWallpaperSubDir)
           .Append(wallpaper_file_id);
   base::FilePath original_wallpaper_dir =
-      WallpaperController::GetCustomWallpaperDir(
-          WallpaperController::kOriginalWallpaperSubDir)
+      WallpaperControllerImpl::GetCustomWallpaperDir(
+          WallpaperControllerImpl::kOriginalWallpaperSubDir)
           .Append(wallpaper_file_id);
 
   while (base::PathExists(small_wallpaper_dir) ||
@@ -220,50 +220,33 @@
   }
 }
 
-// A test implementation of the WallpaperObserver mojo interface.
-class TestWallpaperObserver : public mojom::WallpaperObserver {
- public:
-  TestWallpaperObserver() = default;
-  ~TestWallpaperObserver() override = default;
-
-  // mojom::WallpaperObserver:
-  void OnWallpaperChanged(uint32_t image_id) override {}
-
-  void OnWallpaperColorsChanged(
-      const std::vector<SkColor>& prominent_colors) override {
-    ++wallpaper_colors_changed_count_;
-    if (run_loop_)
-      run_loop_->Quit();
-  }
-
-  void OnWallpaperBlurChanged(bool blurred) override {}
-
-  int wallpaper_colors_changed_count() const {
-    return wallpaper_colors_changed_count_;
-  }
-
-  void set_run_loop(base::RunLoop* loop) { run_loop_ = loop; }
-
- private:
-  base::RunLoop* run_loop_ = nullptr;
-  int wallpaper_colors_changed_count_ = 0;
-
-  DISALLOW_COPY_AND_ASSIGN(TestWallpaperObserver);
-};
-
+// A test implementation of the WallpaperControllerObserver interface.
 class TestWallpaperControllerObserver : public WallpaperControllerObserver {
  public:
-  TestWallpaperControllerObserver() = default;
+  explicit TestWallpaperControllerObserver(WallpaperController* controller)
+      : controller_(controller) {
+    controller_->AddObserver(this);
+  }
 
-  void OnWallpaperBlurChanged() override { ++wallpaper_blur_changed_count_; }
-  void OnFirstWallpaperShown() override { ++first_wallpaper_shown_count_; }
+  ~TestWallpaperControllerObserver() override {
+    controller_->RemoveObserver(this);
+  }
 
-  void Reset() { wallpaper_blur_changed_count_ = 0; }
+  // WallpaperControllerObserver
+  void OnWallpaperColorsChanged() override { ++colors_changed_count_; }
+  void OnWallpaperBlurChanged() override { ++blur_changed_count_; }
+  void OnFirstWallpaperShown() override { ++first_shown_count_; }
 
-  int wallpaper_blur_changed_count_ = 0;
-  int first_wallpaper_shown_count_ = 0;
+  int colors_changed_count() const { return colors_changed_count_; }
+  int blur_changed_count() const { return blur_changed_count_; }
+  int first_shown_count() const { return first_shown_count_; }
 
  private:
+  WallpaperController* controller_;
+  int colors_changed_count_ = 0;
+  int blur_changed_count_ = 0;
+  int first_shown_count_ = 0;
+
   DISALLOW_COPY_AND_ASSIGN(TestWallpaperControllerObserver);
 };
 
@@ -369,16 +352,15 @@
                          base::Time::Now().LocalMidnight());
   }
 
-  // Helper function to create a new |mojom::WallpaperUserInfoPtr| instance with
-  // default values. In addition, clear the wallpaper count and the decoding
-  // request list. May be called multiple times for the same |account_id|.
-  mojom::WallpaperUserInfoPtr InitializeUser(const AccountId& account_id) {
-    mojom::WallpaperUserInfoPtr wallpaper_user_info =
-        mojom::WallpaperUserInfo::New();
-    wallpaper_user_info->account_id = account_id;
-    wallpaper_user_info->type = user_manager::USER_TYPE_REGULAR;
-    wallpaper_user_info->is_ephemeral = false;
-    wallpaper_user_info->has_gaia_account = true;
+  // Helper function to create a |WallpaperUserInfo| structwith default values.
+  // In addition, clear the wallpaper count and the decoding request list. May
+  // be called multiple times for the same |account_id|.
+  WallpaperUserInfo InitializeUser(const AccountId& account_id) {
+    WallpaperUserInfo wallpaper_user_info;
+    wallpaper_user_info.account_id = account_id;
+    wallpaper_user_info.type = user_manager::USER_TYPE_REGULAR;
+    wallpaper_user_info.is_ephemeral = false;
+    wallpaper_user_info.has_gaia_account = true;
     ClearWallpaperCount();
     ClearDecodeFilePaths();
 
@@ -392,10 +374,10 @@
     std::string wallpaper_files_id = GetDummyFileId(account_id);
     std::string file_name = GetDummyFileName(account_id);
     base::FilePath small_wallpaper_path =
-        GetCustomWallpaperPath(WallpaperController::kSmallWallpaperSubDir,
+        GetCustomWallpaperPath(WallpaperControllerImpl::kSmallWallpaperSubDir,
                                wallpaper_files_id, file_name);
     base::FilePath large_wallpaper_path =
-        GetCustomWallpaperPath(WallpaperController::kLargeWallpaperSubDir,
+        GetCustomWallpaperPath(WallpaperControllerImpl::kLargeWallpaperSubDir,
                                wallpaper_files_id, file_name);
 
     // Saves the small/large resolution wallpapers to small/large custom
@@ -482,7 +464,7 @@
 
   // A helper to test the behavior of setting online wallpaper after the image
   // is decoded. This is needed because image decoding is not supported in unit
-  // tests (the connector for the mojo service manager is null).
+  // tests.
   void SetOnlineWallpaperFromImage(
       const AccountId& account_id,
       const gfx::ImageSkia& image,
@@ -490,8 +472,8 @@
       WallpaperLayout layout,
       bool save_file,
       bool preview_mode,
-      WallpaperController::SetOnlineWallpaperFromDataCallback callback) {
-    const WallpaperController::OnlineWallpaperParams params = {
+      WallpaperControllerImpl::SetOnlineWallpaperFromDataCallback callback) {
+    const WallpaperControllerImpl::OnlineWallpaperParams params = {
         account_id, false /*is_ephemeral=*/, url, layout, preview_mode};
     controller_->OnOnlineWallpaperDecoded(params, save_file,
                                           std::move(callback), image);
@@ -508,11 +490,6 @@
   // Wrapper for private ShouldCalculateColors().
   bool ShouldCalculateColors() { return controller_->ShouldCalculateColors(); }
 
-  // Wrapper for private IsActiveUserWallpaperControlledByPolicyImpl().
-  bool IsActiveUserWallpaperControlledByPolicy() {
-    return controller_->IsActiveUserWallpaperControlledByPolicyImpl();
-  }
-
   // Wrapper for private IsDevicePolicyWallpaper().
   bool IsDevicePolicyWallpaper() {
     return controller_->IsDevicePolicyWallpaper();
@@ -538,7 +515,7 @@
     return controller_->GetWallpaperContainerId(controller_->locked_);
   }
 
-  WallpaperController* controller_;  // Not owned.
+  WallpaperControllerImpl* controller_;  // Not owned.
 
   base::ScopedTempDir user_data_dir_;
   base::ScopedTempDir online_wallpaper_dir_;
@@ -550,7 +527,7 @@
 };
 
 TEST_F(WallpaperControllerTest, BasicReparenting) {
-  WallpaperController* controller = Shell::Get()->wallpaper_controller();
+  WallpaperControllerImpl* controller = Shell::Get()->wallpaper_controller();
   controller->CreateEmptyWallpaperForTesting();
 
   // Wallpaper view/window exists in the wallpaper container and nothing is in
@@ -582,7 +559,7 @@
       ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
 
   // Create the wallpaper and its view.
-  WallpaperController* controller = Shell::Get()->wallpaper_controller();
+  WallpaperControllerImpl* controller = Shell::Get()->wallpaper_controller();
   controller->CreateEmptyWallpaperForTesting();
 
   // The new wallpaper is ready to animate.
@@ -607,7 +584,7 @@
       ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
 
   // Reset wallpaper state, see ControllerOwnership above.
-  WallpaperController* controller = Shell::Get()->wallpaper_controller();
+  WallpaperControllerImpl* controller = Shell::Get()->wallpaper_controller();
   controller->CreateEmptyWallpaperForTesting();
 
   // Run wallpaper show animation to completion.
@@ -655,7 +632,7 @@
       ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
 
   // Reset wallpaper state, see ControllerOwnership above.
-  WallpaperController* controller = Shell::Get()->wallpaper_controller();
+  WallpaperControllerImpl* controller = Shell::Get()->wallpaper_controller();
   controller->CreateEmptyWallpaperForTesting();
 
   // Run wallpaper show animation to completion.
@@ -720,32 +697,32 @@
   // Device scale factor shouldn't affect the native size.
   UpdateDisplay("1000x300*2");
   EXPECT_EQ("1000x300",
-            WallpaperController::GetMaxDisplaySizeInNative().ToString());
+            WallpaperControllerImpl::GetMaxDisplaySizeInNative().ToString());
 
   // Rotated display should return the rotated size.
   UpdateDisplay("1000x300*2/r");
   EXPECT_EQ("300x1000",
-            WallpaperController::GetMaxDisplaySizeInNative().ToString());
+            WallpaperControllerImpl::GetMaxDisplaySizeInNative().ToString());
 
   // UI Scaling shouldn't affect the native size.
   UpdateDisplay("1000x300*2@1.5");
   EXPECT_EQ("1000x300",
-            WallpaperController::GetMaxDisplaySizeInNative().ToString());
+            WallpaperControllerImpl::GetMaxDisplaySizeInNative().ToString());
 
   // First display has maximum size.
   UpdateDisplay("400x300,100x100");
   EXPECT_EQ("400x300",
-            WallpaperController::GetMaxDisplaySizeInNative().ToString());
+            WallpaperControllerImpl::GetMaxDisplaySizeInNative().ToString());
 
   // Second display has maximum size.
   UpdateDisplay("400x300,500x600");
   EXPECT_EQ("500x600",
-            WallpaperController::GetMaxDisplaySizeInNative().ToString());
+            WallpaperControllerImpl::GetMaxDisplaySizeInNative().ToString());
 
   // Maximum width and height belongs to different displays.
   UpdateDisplay("400x300,100x500");
   EXPECT_EQ("400x500",
-            WallpaperController::GetMaxDisplaySizeInNative().ToString());
+            WallpaperControllerImpl::GetMaxDisplaySizeInNative().ToString());
 }
 
 // Test that the wallpaper is always fitted to the native display resolution
@@ -859,27 +836,15 @@
   EXPECT_FALSE(ShouldCalculateColors());
 }
 
-TEST_F(WallpaperControllerTest, MojoWallpaperObserverTest) {
-  TestWallpaperObserver observer;
-  mojom::WallpaperObserverAssociatedPtr observer_ptr;
-  mojo::AssociatedBinding<mojom::WallpaperObserver> binding(
-      &observer, mojo::MakeRequestAssociatedWithDedicatedPipe(&observer_ptr));
-  controller_->AddObserver(observer_ptr.PassInterface());
-  controller_->FlushForTesting();
-
-  // Adding an observer fires OnWallpaperColorsChanged() immediately.
-  EXPECT_EQ(1, observer.wallpaper_colors_changed_count());
+TEST_F(WallpaperControllerTest, EnableShelfColoringNotifiesObservers) {
+  TestWallpaperControllerObserver observer(controller_);
+  EXPECT_EQ(0, observer.colors_changed_count());
 
   // Enable shelf coloring will set a customized wallpaper image and change
   // session state to ACTIVE, which will trigger wallpaper colors calculation.
-  base::RunLoop run_loop;
-  observer.set_run_loop(&run_loop);
   EnableShelfColoring();
-  // Color calculation may be asynchronous.
-  run_loop.Run();
-  // Mojo methods are called after color calculation finishes.
-  controller_->FlushForTesting();
-  EXPECT_EQ(2, observer.wallpaper_colors_changed_count());
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(1, observer.colors_changed_count());
 }
 
 TEST_F(WallpaperControllerTest, SetCustomWallpaper) {
@@ -961,7 +926,7 @@
   controller_->SetOnlineWallpaperFromData(
       InitializeUser(account_id_1), std::string() /*image_data=*/, kDummyUrl,
       layout, false /*preview_mode=*/,
-      WallpaperController::SetOnlineWallpaperFromDataCallback());
+      WallpaperControllerImpl::SetOnlineWallpaperFromDataCallback());
   RunAllTasksUntilIdle();
   EXPECT_EQ(1, GetWallpaperCount());
   EXPECT_EQ(controller_->GetWallpaperType(), ONLINE);
@@ -1015,7 +980,7 @@
   controller_->SetOnlineWallpaperFromData(
       InitializeUser(account_id_1), std::string() /*image_data=*/, kDummyUrl2,
       layout, false /*preview_mode=*/,
-      WallpaperController::SetOnlineWallpaperFromDataCallback());
+      WallpaperControllerImpl::SetOnlineWallpaperFromDataCallback());
   RunAllTasksUntilIdle();
   EXPECT_EQ(0, GetWallpaperCount());
   EXPECT_TRUE(controller_->GetUserWallpaperInfo(account_id_1, &wallpaper_info,
@@ -1146,21 +1111,11 @@
   // Set a third-party wallpaper for |kUser1|.
   const WallpaperLayout layout = WALLPAPER_LAYOUT_CENTER;
   gfx::ImageSkia third_party_wallpaper = CreateImage(640, 480, kWallpaperColor);
-  bool allowed_to_update_wallpaper = false;
-  std::unique_ptr<base::RunLoop> run_loop = std::make_unique<base::RunLoop>();
-  controller_->SetThirdPartyWallpaper(
+  EXPECT_TRUE(controller_->SetThirdPartyWallpaper(
       InitializeUser(account_id_1), wallpaper_files_id_1, file_name_1, layout,
-      third_party_wallpaper,
-      base::BindLambdaForTesting([&allowed_to_update_wallpaper, &run_loop](
-                                     bool allowed, uint32_t image_id) {
-        allowed_to_update_wallpaper = allowed;
-        run_loop->Quit();
-      }));
-  run_loop->Run();
+      third_party_wallpaper));
   // Verify the wallpaper is shown.
   EXPECT_EQ(1, GetWallpaperCount());
-  // Verify the callback function gets the correct value.
-  EXPECT_TRUE(allowed_to_update_wallpaper);
   // Verify the user wallpaper info is updated.
   EXPECT_TRUE(controller_->GetUserWallpaperInfo(account_id_1, &wallpaper_info,
                                                 false /*is_ephemeral=*/));
@@ -1170,23 +1125,14 @@
   EXPECT_EQ(wallpaper_info, expected_wallpaper_info);
 
   // Switch active user to |kUser2|, but set another third-party wallpaper for
-  // |kUser1|.
-  allowed_to_update_wallpaper = true;
+  // |kUser1|; the operation should not be allowed, because |kUser1| is not the
+  // active user.
   SimulateUserLogin(kUser2);
-  run_loop.reset(new base::RunLoop());
-  controller_->SetThirdPartyWallpaper(
+  EXPECT_FALSE(controller_->SetThirdPartyWallpaper(
       InitializeUser(account_id_1), wallpaper_files_id_2, file_name_2, layout,
-      third_party_wallpaper,
-      base::BindLambdaForTesting([&allowed_to_update_wallpaper, &run_loop](
-                                     bool allowed, uint32_t image_id) {
-        allowed_to_update_wallpaper = allowed;
-        run_loop->Quit();
-      }));
-  run_loop->Run();
-  // Verify the wallpaper is not shown because |kUser1| is not the active user.
+      third_party_wallpaper));
+  // Verify the wallpaper is not shown.
   EXPECT_EQ(0, GetWallpaperCount());
-  // Verify the callback function gets the correct value.
-  EXPECT_FALSE(allowed_to_update_wallpaper);
   // Verify the wallpaper info for |kUser1| is updated, because setting
   // wallpaper is still allowed for non-active users.
   EXPECT_TRUE(controller_->GetUserWallpaperInfo(account_id_1, &wallpaper_info,
@@ -1204,30 +1150,20 @@
   RunAllTasksUntilIdle();
   EXPECT_TRUE(
       controller_->IsPolicyControlled(account_id_2, false /*is_ephemeral=*/));
-  EXPECT_TRUE(IsActiveUserWallpaperControlledByPolicy());
+  EXPECT_TRUE(controller_->IsActiveUserWallpaperControlledByPolicy());
 
-  // Set a third-party wallpaper for |kUser2|.
-  allowed_to_update_wallpaper = true;
-  run_loop.reset(new base::RunLoop());
-  controller_->SetThirdPartyWallpaper(
+  // Setting a third-party wallpaper for |kUser2| should not be allowed, because
+  // third-party wallpapers cannot be set for policy controlled users.
+  EXPECT_FALSE(controller_->SetThirdPartyWallpaper(
       InitializeUser(account_id_2), wallpaper_files_id_1, file_name_1, layout,
-      third_party_wallpaper,
-      base::BindLambdaForTesting([&allowed_to_update_wallpaper, &run_loop](
-                                     bool allowed, uint32_t image_id) {
-        allowed_to_update_wallpaper = allowed;
-        run_loop->Quit();
-      }));
-  run_loop->Run();
-  // Verify the wallpaper is not shown because third-party wallpaper cannot be
-  // set for policy controlled users.
+      third_party_wallpaper));
+  // Verify the wallpaper is not shown.
   EXPECT_EQ(0, GetWallpaperCount());
-  // Verify the callback gets the correct value.
-  EXPECT_FALSE(allowed_to_update_wallpaper);
   // Verify |kUser2| is still policy controlled and has the policy wallpaper
   // info.
   EXPECT_TRUE(
       controller_->IsPolicyControlled(account_id_2, false /*is_ephemeral=*/));
-  EXPECT_TRUE(IsActiveUserWallpaperControlledByPolicy());
+  EXPECT_TRUE(controller_->IsActiveUserWallpaperControlledByPolicy());
   EXPECT_TRUE(controller_->GetUserWallpaperInfo(account_id_2, &wallpaper_info,
                                                 false /*is_ephemeral=*/));
   WallpaperInfo policy_wallpaper_info(base::FilePath(wallpaper_files_id_2)
@@ -1327,12 +1263,10 @@
   // path.
   UpdateDisplay("1600x1200");
   RunAllTasksUntilIdle();
-  mojom::WallpaperUserInfoPtr wallpaper_user_info =
-      InitializeUser(child_account_id);
-  wallpaper_user_info->type = user_manager::USER_TYPE_CHILD;
-  controller_->SetDefaultWallpaper(std::move(wallpaper_user_info),
-                                   child_wallpaper_files_id,
-                                   true /*show_wallpaper=*/);
+  WallpaperUserInfo wallpaper_user_info = InitializeUser(child_account_id);
+  wallpaper_user_info.type = user_manager::USER_TYPE_CHILD;
+  controller_->SetDefaultWallpaper(
+      wallpaper_user_info, child_wallpaper_files_id, true /*show_wallpaper=*/);
   RunAllTasksUntilIdle();
   EXPECT_EQ(1, GetWallpaperCount());
   EXPECT_EQ(controller_->GetWallpaperType(), DEFAULT);
@@ -1345,10 +1279,9 @@
   UpdateDisplay("800x600");
   RunAllTasksUntilIdle();
   wallpaper_user_info = InitializeUser(child_account_id);
-  wallpaper_user_info->type = user_manager::USER_TYPE_CHILD;
-  controller_->SetDefaultWallpaper(std::move(wallpaper_user_info),
-                                   child_wallpaper_files_id,
-                                   true /*show_wallpaper=*/);
+  wallpaper_user_info.type = user_manager::USER_TYPE_CHILD;
+  controller_->SetDefaultWallpaper(
+      wallpaper_user_info, child_wallpaper_files_id, true /*show_wallpaper=*/);
   RunAllTasksUntilIdle();
   EXPECT_EQ(1, GetWallpaperCount());
   EXPECT_EQ(controller_->GetWallpaperType(), DEFAULT);
@@ -1525,7 +1458,7 @@
   controller_->SetOnlineWallpaperFromData(
       InitializeUser(account_id_1), std::string() /*image_data=*/, kDummyUrl,
       WALLPAPER_LAYOUT_CENTER, false /*preview_mode=*/,
-      WallpaperController::SetOnlineWallpaperFromDataCallback());
+      WallpaperControllerImpl::SetOnlineWallpaperFromDataCallback());
   RunAllTasksUntilIdle();
   EXPECT_TRUE(
       controller_->GetWallpaperFromCache(account_id_1, &cached_wallpaper));
@@ -1569,10 +1502,10 @@
 TEST_F(WallpaperControllerTest, ShowCustomWallpaperWithCorrectResolution) {
   CreateDefaultWallpapers();
   const base::FilePath small_custom_wallpaper_path =
-      GetCustomWallpaperPath(WallpaperController::kSmallWallpaperSubDir,
+      GetCustomWallpaperPath(WallpaperControllerImpl::kSmallWallpaperSubDir,
                              wallpaper_files_id_1, file_name_1);
   const base::FilePath large_custom_wallpaper_path =
-      GetCustomWallpaperPath(WallpaperController::kLargeWallpaperSubDir,
+      GetCustomWallpaperPath(WallpaperControllerImpl::kLargeWallpaperSubDir,
                              wallpaper_files_id_1, file_name_1);
   const base::FilePath small_default_wallpaper_path =
       default_wallpaper_dir_.GetPath().Append(kDefaultSmallWallpaperName);
@@ -1760,7 +1693,7 @@
   controller_->SetOnlineWallpaperFromData(
       InitializeUser(account_id_1), std::string() /*image_data=*/, kDummyUrl,
       layout, false /*preview_mode=*/,
-      WallpaperController::SetOnlineWallpaperFromDataCallback());
+      WallpaperControllerImpl::SetOnlineWallpaperFromDataCallback());
   RunAllTasksUntilIdle();
   EXPECT_EQ(1, GetWallpaperCount());
   EXPECT_EQ(controller_->GetWallpaperType(), ONLINE);
@@ -1790,7 +1723,7 @@
 TEST_F(WallpaperControllerTest, RemoveUserWithCustomWallpaper) {
   SimulateUserLogin(kUser1);
   base::FilePath small_wallpaper_path_1 =
-      GetCustomWallpaperPath(WallpaperController::kSmallWallpaperSubDir,
+      GetCustomWallpaperPath(WallpaperControllerImpl::kSmallWallpaperSubDir,
                              wallpaper_files_id_1, file_name_1);
   // Set a custom wallpaper for |kUser1| and verify the wallpaper exists.
   CreateAndSaveWallpapers(account_id_1);
@@ -1799,7 +1732,7 @@
   // Now login another user and set a custom wallpaper for the user.
   SimulateUserLogin(kUser2);
   base::FilePath small_wallpaper_path_2 = GetCustomWallpaperPath(
-      WallpaperController::kSmallWallpaperSubDir, wallpaper_files_id_2,
+      WallpaperControllerImpl::kSmallWallpaperSubDir, wallpaper_files_id_2,
       GetDummyFileName(account_id_2));
   CreateAndSaveWallpapers(account_id_2);
   EXPECT_TRUE(base::PathExists(small_wallpaper_path_2));
@@ -1821,7 +1754,7 @@
 TEST_F(WallpaperControllerTest, RemoveUserWithDefaultWallpaper) {
   SimulateUserLogin(kUser1);
   base::FilePath small_wallpaper_path_1 =
-      GetCustomWallpaperPath(WallpaperController::kSmallWallpaperSubDir,
+      GetCustomWallpaperPath(WallpaperControllerImpl::kSmallWallpaperSubDir,
                              wallpaper_files_id_1, file_name_1);
   // Set a custom wallpaper for |kUser1| and verify the wallpaper exists.
   CreateAndSaveWallpapers(account_id_1);
@@ -1846,78 +1779,73 @@
   // Simulate the login screen. Verify that it returns false since there's no
   // active user.
   ClearLogin();
-  EXPECT_FALSE(IsActiveUserWallpaperControlledByPolicy());
+  EXPECT_FALSE(controller_->IsActiveUserWallpaperControlledByPolicy());
 
   SimulateUserLogin(kUser1);
-  EXPECT_FALSE(IsActiveUserWallpaperControlledByPolicy());
+  EXPECT_FALSE(controller_->IsActiveUserWallpaperControlledByPolicy());
   // Set a policy wallpaper for the active user. Verify that the active user
   // becomes policy controlled.
   controller_->SetPolicyWallpaper(InitializeUser(account_id_1),
                                   wallpaper_files_id_1,
                                   std::string() /*data=*/);
   RunAllTasksUntilIdle();
-  EXPECT_TRUE(IsActiveUserWallpaperControlledByPolicy());
+  EXPECT_TRUE(controller_->IsActiveUserWallpaperControlledByPolicy());
 
   // Switch the active user. Verify the active user is not policy controlled.
   SimulateUserLogin(kUser2);
-  EXPECT_FALSE(IsActiveUserWallpaperControlledByPolicy());
+  EXPECT_FALSE(controller_->IsActiveUserWallpaperControlledByPolicy());
 
   // Logs out. Verify that it returns false since there's no active user.
   ClearLogin();
-  EXPECT_FALSE(IsActiveUserWallpaperControlledByPolicy());
+  EXPECT_FALSE(controller_->IsActiveUserWallpaperControlledByPolicy());
 }
 
 TEST_F(WallpaperControllerTest, WallpaperBlur) {
+  TestWallpaperControllerObserver observer(controller_);
+
   ASSERT_TRUE(controller_->IsBlurAllowed());
   ASSERT_FALSE(controller_->IsWallpaperBlurred());
 
-  TestWallpaperControllerObserver observer;
-  controller_->AddObserver(&observer);
-
   SetSessionState(SessionState::ACTIVE);
   EXPECT_FALSE(controller_->IsWallpaperBlurred());
-  EXPECT_EQ(0, observer.wallpaper_blur_changed_count_);
+  EXPECT_EQ(0, observer.blur_changed_count());
 
   SetSessionState(SessionState::LOCKED);
   EXPECT_TRUE(controller_->IsWallpaperBlurred());
-  EXPECT_EQ(1, observer.wallpaper_blur_changed_count_);
+  EXPECT_EQ(1, observer.blur_changed_count());
 
   SetSessionState(SessionState::LOGGED_IN_NOT_ACTIVE);
   EXPECT_FALSE(controller_->IsWallpaperBlurred());
-  EXPECT_EQ(2, observer.wallpaper_blur_changed_count_);
+  EXPECT_EQ(2, observer.blur_changed_count());
 
   SetSessionState(SessionState::LOGIN_SECONDARY);
   EXPECT_TRUE(controller_->IsWallpaperBlurred());
-  EXPECT_EQ(3, observer.wallpaper_blur_changed_count_);
+  EXPECT_EQ(3, observer.blur_changed_count());
 
   // Blur state does not change below.
-  observer.Reset();
   SetSessionState(SessionState::LOGIN_PRIMARY);
   EXPECT_TRUE(controller_->IsWallpaperBlurred());
-  EXPECT_EQ(0, observer.wallpaper_blur_changed_count_);
+  EXPECT_EQ(3, observer.blur_changed_count());
 
   SetSessionState(SessionState::OOBE);
   EXPECT_TRUE(controller_->IsWallpaperBlurred());
-  EXPECT_EQ(0, observer.wallpaper_blur_changed_count_);
+  EXPECT_EQ(3, observer.blur_changed_count());
 
   SetSessionState(SessionState::UNKNOWN);
   EXPECT_TRUE(controller_->IsWallpaperBlurred());
-  EXPECT_EQ(0, observer.wallpaper_blur_changed_count_);
-
-  controller_->RemoveObserver(&observer);
+  EXPECT_EQ(3, observer.blur_changed_count());
 }
 
 TEST_F(WallpaperControllerTest, WallpaperBlurDuringLockScreenTransition) {
+  TestWallpaperControllerObserver observer(controller_);
+
   ASSERT_TRUE(controller_->IsBlurAllowed());
   ASSERT_FALSE(controller_->IsWallpaperBlurred());
 
-  TestWallpaperControllerObserver observer;
-  controller_->AddObserver(&observer);
-
   // Simulate lock and unlock sequence.
   controller_->UpdateWallpaperBlur(true);
   EXPECT_TRUE(controller_->IsWallpaperBlurred());
-  EXPECT_EQ(1, observer.wallpaper_blur_changed_count_);
+  EXPECT_EQ(1, observer.blur_changed_count());
 
   SetSessionState(SessionState::LOCKED);
   EXPECT_TRUE(controller_->IsWallpaperBlurred());
@@ -1926,9 +1854,7 @@
   // UpdateWallpaperBlur(false)
   SetSessionState(SessionState::ACTIVE);
   EXPECT_FALSE(controller_->IsWallpaperBlurred());
-  EXPECT_EQ(2, observer.wallpaper_blur_changed_count_);
-
-  controller_->RemoveObserver(&observer);
+  EXPECT_EQ(2, observer.blur_changed_count());
 }
 
 TEST_F(WallpaperControllerTest, OnlyShowDevicePolicyWallpaperOnLoginScreen) {
@@ -2194,7 +2120,7 @@
   SetOnlineWallpaperFromImage(
       account_id_1, online_wallpaper, kDummyUrl, layout, false /*save_file=*/,
       true /*preview_mode=*/,
-      WallpaperController::SetOnlineWallpaperFromDataCallback());
+      WallpaperControllerImpl::SetOnlineWallpaperFromDataCallback());
   RunAllTasksUntilIdle();
   EXPECT_EQ(1, GetWallpaperCount());
   EXPECT_EQ(online_wallpaper_color, GetWallpaperColor());
@@ -2294,7 +2220,7 @@
   SetOnlineWallpaperFromImage(
       account_id_1, online_wallpaper, kDummyUrl, layout, false /*save_file=*/,
       true /*preview_mode=*/,
-      WallpaperController::SetOnlineWallpaperFromDataCallback());
+      WallpaperControllerImpl::SetOnlineWallpaperFromDataCallback());
   RunAllTasksUntilIdle();
   EXPECT_EQ(1, GetWallpaperCount());
   EXPECT_EQ(kWallpaperColor, GetWallpaperColor());
@@ -2312,7 +2238,7 @@
   SetOnlineWallpaperFromImage(
       account_id_1, synced_online_wallpaper, kDummyUrl2, layout,
       false /*save_file=*/, false /*preview_mode=*/,
-      WallpaperController::SetOnlineWallpaperFromDataCallback());
+      WallpaperControllerImpl::SetOnlineWallpaperFromDataCallback());
   RunAllTasksUntilIdle();
   EXPECT_EQ(0, GetWallpaperCount());
   EXPECT_EQ(kWallpaperColor, GetWallpaperColor());
@@ -2443,10 +2369,9 @@
 }
 
 TEST_F(WallpaperControllerTest, OnFirstWallpaperShown) {
-  TestWallpaperControllerObserver observer;
-  controller_->AddObserver(&observer);
+  TestWallpaperControllerObserver observer(controller_);
   EXPECT_EQ(0, GetWallpaperCount());
-  EXPECT_EQ(0, observer.first_wallpaper_shown_count_);
+  EXPECT_EQ(0, observer.first_shown_count());
   // Show the first wallpaper, verify the observer is notified.
   controller_->ShowWallpaperImage(CreateImage(640, 480, SK_ColorBLUE),
                                   CreateWallpaperInfo(WALLPAPER_LAYOUT_STRETCH),
@@ -2455,7 +2380,7 @@
   RunAllTasksUntilIdle();
   EXPECT_EQ(SK_ColorBLUE, GetWallpaperColor());
   EXPECT_EQ(1, GetWallpaperCount());
-  EXPECT_EQ(1, observer.first_wallpaper_shown_count_);
+  EXPECT_EQ(1, observer.first_shown_count());
   // Show the second wallpaper, verify the observer is not notified.
   controller_->ShowWallpaperImage(CreateImage(640, 480, SK_ColorCYAN),
                                   CreateWallpaperInfo(WALLPAPER_LAYOUT_STRETCH),
@@ -2464,17 +2389,15 @@
   RunAllTasksUntilIdle();
   EXPECT_EQ(SK_ColorCYAN, GetWallpaperColor());
   EXPECT_EQ(2, GetWallpaperCount());
-  EXPECT_EQ(1, observer.first_wallpaper_shown_count_);
-  controller_->RemoveObserver(&observer);
+  EXPECT_EQ(1, observer.first_shown_count());
 }
 
 // Although ephemeral users' custom wallpapers are not saved to disk, they
 // should be kept within the user session. Test for https://crbug.com/825237.
 TEST_F(WallpaperControllerTest, ShowWallpaperForEphemeralUser) {
   auto initialize_ephemeral_user = [&](const AccountId& account_id) {
-    mojom::WallpaperUserInfoPtr wallpaper_user_info =
-        InitializeUser(account_id);
-    wallpaper_user_info->is_ephemeral = true;
+    WallpaperUserInfo wallpaper_user_info = InitializeUser(account_id);
+    wallpaper_user_info.is_ephemeral = true;
     return wallpaper_user_info;
   };
 
diff --git a/ash/wallpaper/wallpaper_utils/wallpaper_resizer.h b/ash/wallpaper/wallpaper_utils/wallpaper_resizer.h
index f0b9efc0..bc78add8 100644
--- a/ash/wallpaper/wallpaper_utils/wallpaper_resizer.h
+++ b/ash/wallpaper/wallpaper_utils/wallpaper_resizer.h
@@ -8,7 +8,7 @@
 #include <stdint.h>
 
 #include "ash/ash_export.h"
-#include "ash/wallpaper/wallpaper_info.h"
+#include "ash/public/cpp/wallpaper_info.h"
 #include "ash/wallpaper/wallpaper_utils/wallpaper_resizer_observer.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
diff --git a/ash/wallpaper/wallpaper_view.cc b/ash/wallpaper/wallpaper_view.cc
index 3783273e..46e19e3 100644
--- a/ash/wallpaper/wallpaper_view.cc
+++ b/ash/wallpaper/wallpaper_view.cc
@@ -8,7 +8,7 @@
 #include "ash/root_window_controller.h"
 #include "ash/session/session_controller_impl.h"
 #include "ash/shell.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "ash/wallpaper/wallpaper_widget_controller.h"
 #include "ash/wm/overview/overview_controller.h"
 #include "ash/wm/overview/overview_utils.h"
@@ -210,7 +210,7 @@
                                      int blur,
                                      float opacity,
                                      WallpaperView** out_wallpaper_view) {
-  WallpaperController* controller = Shell::Get()->wallpaper_controller();
+  auto* controller = Shell::Get()->wallpaper_controller();
 
   views::Widget* wallpaper_widget = new views::Widget;
   views::Widget::InitParams params(
diff --git a/ash/wallpaper/wallpaper_widget_controller.cc b/ash/wallpaper/wallpaper_widget_controller.cc
index 73eabab0..f6b2395 100644
--- a/ash/wallpaper/wallpaper_widget_controller.cc
+++ b/ash/wallpaper/wallpaper_widget_controller.cc
@@ -9,7 +9,7 @@
 #include "ash/ash_export.h"
 #include "ash/root_window_controller.h"
 #include "ash/shell.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "base/scoped_observer.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_observer.h"
diff --git a/ash/wm/lock_state_controller.cc b/ash/wm/lock_state_controller.cc
index f21237a..aed6ed59 100644
--- a/ash/wm/lock_state_controller.cc
+++ b/ash/wm/lock_state_controller.cc
@@ -17,7 +17,7 @@
 #include "ash/shell_delegate.h"
 #include "ash/shutdown_controller.h"
 #include "ash/shutdown_reason.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "ash/wm/session_state_animator.h"
 #include "ash/wm/session_state_animator_impl.h"
 #include "base/bind.h"
diff --git a/ash/wm/overview/overview_controller.cc b/ash/wm/overview/overview_controller.cc
index 049d959..f97087ca 100644
--- a/ash/wm/overview/overview_controller.cc
+++ b/ash/wm/overview/overview_controller.cc
@@ -13,7 +13,7 @@
 #include "ash/scoped_animation_disabler.h"
 #include "ash/session/session_controller_impl.h"
 #include "ash/shell.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "ash/wallpaper/wallpaper_view.h"
 #include "ash/wallpaper/wallpaper_widget_controller.h"
 #include "ash/wm/mru_window_tracker.h"
diff --git a/ash/wm/splitview/split_view_controller_unittest.cc b/ash/wm/splitview/split_view_controller_unittest.cc
index 0d589fd..71be4014 100644
--- a/ash/wm/splitview/split_view_controller_unittest.cc
+++ b/ash/wm/splitview/split_view_controller_unittest.cc
@@ -22,7 +22,6 @@
 #include "ash/system/status_area_widget.h"
 #include "ash/system/status_area_widget_test_helper.h"
 #include "ash/test/ash_test_base.h"
-#include "ash/wallpaper/wallpaper_controller.h"
 #include "ash/wm/desks/desks_util.h"
 #include "ash/wm/drag_window_resizer.h"
 #include "ash/wm/mru_window_tracker.h"
diff --git a/ash/wm/workspace/backdrop_controller.cc b/ash/wm/workspace/backdrop_controller.cc
index 6cbeb55..eb292da 100644
--- a/ash/wm/workspace/backdrop_controller.cc
+++ b/ash/wm/workspace/backdrop_controller.cc
@@ -15,7 +15,7 @@
 #include "ash/public/cpp/window_properties.h"
 #include "ash/screen_util.h"
 #include "ash/shell.h"
-#include "ash/wallpaper/wallpaper_controller.h"
+#include "ash/wallpaper/wallpaper_controller_impl.h"
 #include "ash/wm/always_on_top_controller.h"
 #include "ash/wm/desks/desks_util.h"
 #include "ash/wm/overview/overview_controller.h"
diff --git a/ash/wm/workspace/backdrop_controller.h b/ash/wm/workspace/backdrop_controller.h
index 6cc60d1..a2aaf0c 100644
--- a/ash/wm/workspace/backdrop_controller.h
+++ b/ash/wm/workspace/backdrop_controller.h
@@ -10,8 +10,8 @@
 #include "ash/accessibility/accessibility_observer.h"
 #include "ash/ash_export.h"
 #include "ash/public/cpp/split_view.h"
+#include "ash/public/cpp/wallpaper_controller_observer.h"
 #include "ash/shell_observer.h"
-#include "ash/wallpaper/wallpaper_controller_observer.h"
 #include "ash/wm/overview/overview_observer.h"
 #include "base/macros.h"
 #include "ui/gfx/geometry/rect.h"
diff --git a/build/android/generate_jacoco_report.py b/build/android/generate_jacoco_report.py
index cb18c96..ce85773 100755
--- a/build/android/generate_jacoco_report.py
+++ b/build/android/generate_jacoco_report.py
@@ -133,8 +133,7 @@
     source_dirs: A list of source directories of Java source files.
 
   Raises:
-    Exception: No Jacoco xml report found or
-      cannot find package directory according to src root.
+    Exception: No Jacoco xml report found.
   """
   if not os.path.exists(jacoco_xml_path):
     raise Exception('No Jacoco xml report found on %s' % jacoco_xml_path)
@@ -152,11 +151,17 @@
     # Find package directory according to src root.
     package_source_dir = ''
     for source_dir in source_dirs:
+      # Filter out 'out/...' source directories.
+      if source_dir.startswith('out/'):
+        continue
       if package_path in source_dir:
         package_source_dir = source_dir
         break
+    # TODO(crbug/966918): Skip auto-generated Java files/packages for now.
     if not package_source_dir:
-      raise Exception('Cannot find package directory according to src root')
+      print('Cannot find package %s directory according to src root' %
+            package_path)
+      continue
 
     for sourcefile in package.iter('sourcefile'):
       sourcefile_name = sourcefile.attrib['name']
diff --git a/build/config/c++/BUILD.gn b/build/config/c++/BUILD.gn
index b18e49f..45af7c8 100644
--- a/build/config/c++/BUILD.gn
+++ b/build/config/c++/BUILD.gn
@@ -15,6 +15,11 @@
   # TODO(thomasanderson): Set this to true by default once rL352899 is available
   # in MacOS's lldb.
   libcxx_abi_unstable = !((is_mac || is_ios) && is_debug && is_component_build)
+
+  # Builds libcxx Natvis into the symbols for type visualization.
+  # Set to false to workaround http://crbug.com/966676 and
+  # http://crbug.com/966687.
+  libcxx_natvis_include = true
 }
 
 # TODO(xiaohuic): https://crbug/917533 Crashes on internal ChromeOS build.
@@ -78,7 +83,9 @@
 
     # Add a debug visualizer for Microsoft's debuggers so that they can display
     # libc++ types well.
-    ldflags += [ "/NATVIS:" + rebase_path("libc++.natvis", root_build_dir) ]
+    if (libcxx_natvis_include) {
+      ldflags += [ "/NATVIS:" + rebase_path("libc++.natvis", root_build_dir) ]
+    }
   } else {
     cflags_cc += [
       "-nostdinc++",
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index f83a7b1..4da37839 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-8912228414512885520
\ No newline at end of file
+8912196161732498096
\ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index 7945ee6..a024301 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-8912230475324815216
\ No newline at end of file
+8912200482316115744
\ No newline at end of file
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc
index 34007a05..bfed515 100644
--- a/cc/layers/layer.cc
+++ b/cc/layers/layer.cc
@@ -1268,9 +1268,22 @@
   SetSubtreePropertyChanged();
 }
 
+#if DCHECK_IS_ON()
+std::string Layer::DebugName() const {
+  if (inputs_.client) {
+    if (auto debug_info = inputs_.client->TakeDebugInfo(this))
+      return debug_info->ToBaseValue()->FindKey("layer_name")->GetString();
+  }
+  return "";
+}
+#endif
+
 std::string Layer::ToString() const {
   return base::StringPrintf(
       "layer_id: %d\n"
+#if DCHECK_IS_ON()
+      "  name: %s\n"
+#endif
       "  Bounds: %s\n"
       "  ElementId: %s\n"
       "  OffsetToTransformParent: %s\n"
@@ -1280,7 +1293,11 @@
       "  effect_tree_index: %d\n"
       "  scroll_tree_index: %d\n"
       "  transform_tree_index: %d\n",
-      id(), bounds().ToString().c_str(), element_id().ToString().c_str(),
+      id(),
+#if DCHECK_IS_ON()
+      DebugName().c_str(),
+#endif
+      bounds().ToString().c_str(), element_id().ToString().c_str(),
       offset_to_transform_parent().ToString().c_str(),
       position().ToString().c_str(), scrollable(), clip_tree_index(),
       effect_tree_index(), scroll_tree_index(), transform_tree_index());
diff --git a/cc/layers/layer.h b/cc/layers/layer.h
index 1548b3e..ad99204 100644
--- a/cc/layers/layer.h
+++ b/cc/layers/layer.h
@@ -798,6 +798,11 @@
     return should_flatten_screen_space_transform_from_property_tree_;
   }
 
+#if DCHECK_IS_ON()
+  // For debugging, containing information about the associated DOM, etc.
+  std::string DebugName() const;
+#endif
+
   std::string ToString() const;
 
   // Called when a property has been modified in a way that the layer knows
diff --git a/cc/layers/layer_client.h b/cc/layers/layer_client.h
index c7bb486..fb4b6408 100644
--- a/cc/layers/layer_client.h
+++ b/cc/layers/layer_client.h
@@ -29,7 +29,7 @@
   // A pointer to the layer is provided for the convenience of layer clients
   // which service multiple layers.
   virtual std::unique_ptr<base::trace_event::TracedValue> TakeDebugInfo(
-      Layer* layer) = 0;
+      const Layer* layer) = 0;
 
   virtual void DidChangeScrollbarsHiddenIfOverlay(bool) = 0;
 
diff --git a/cc/test/DEPS b/cc/test/DEPS
index ad941a2..1902a72 100644
--- a/cc/test/DEPS
+++ b/cc/test/DEPS
@@ -7,7 +7,6 @@
   "+gpu/command_buffer/client/shared_memory_limits.h",
   "+gpu/command_buffer/common/context_creation_attribs.h",
   "+gpu/command_buffer/common/skia_utils.h",
-  "+gpu/command_buffer/service/gpu_switches.h",
   "+gpu/command_buffer/service/image_factory.h",
   "+gpu/config/gpu_feature_type.h",
   "+gpu/config/gpu_info.h",
diff --git a/cc/test/mock_layer_client.h b/cc/test/mock_layer_client.h
index 0850d24a..e3775ae 100644
--- a/cc/test/mock_layer_client.h
+++ b/cc/test/mock_layer_client.h
@@ -21,7 +21,7 @@
   MockLayerClient& operator=(const MockLayerClient&) = delete;
 
   MOCK_METHOD1(TakeDebugInfo,
-               std::unique_ptr<base::trace_event::TracedValue>(Layer*));
+               std::unique_ptr<base::trace_event::TracedValue>(const Layer*));
   MOCK_METHOD1(didChangeScrollbarsHiddenIfOverlay, void(bool));
 };
 
diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc
index 1eaf504..8b30c94 100644
--- a/cc/test/pixel_test.cc
+++ b/cc/test/pixel_test.cc
@@ -40,7 +40,6 @@
 #include "components/viz/test/test_shared_bitmap_manager.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
 #include "gpu/command_buffer/client/shared_memory_limits.h"
-#include "gpu/command_buffer/service/gpu_switches.h"
 #include "gpu/command_buffer/service/service_utils.h"
 #include "gpu/config/gpu_feature_type.h"
 #include "gpu/config/gpu_info.h"
@@ -272,12 +271,7 @@
   renderer_->SetVisible(true);
 }
 
-void PixelTest::SetUpSkiaRenderer(bool flipped_output_surface,
-                                  bool enable_vulkan) {
-  if (enable_vulkan) {
-    base::CommandLine::ForCurrentProcess()->AppendSwitch(
-        ::switches::kEnableVulkan);
-  }
+void PixelTest::SetUpSkiaRenderer(bool flipped_output_surface) {
   // Set up the GPU service.
   gpu_service_holder_ = viz::TestGpuServiceHolder::GetInstance();
 
diff --git a/cc/test/pixel_test.h b/cc/test/pixel_test.h
index adac588..e410031 100644
--- a/cc/test/pixel_test.h
+++ b/cc/test/pixel_test.h
@@ -112,7 +112,7 @@
 
   void SetUpGLWithoutRenderer(bool flipped_output_surface);
   void SetUpGLRenderer(bool flipped_output_surface);
-  void SetUpSkiaRenderer(bool flipped_output_surface, bool enable_vulkan);
+  void SetUpSkiaRenderer(bool flipped_output_surface);
   void SetUpSoftwareRenderer();
 
   void TearDown() override;
@@ -207,35 +207,6 @@
                      mode) {}
 };
 
-class VulkanSkiaRenderer : public viz::SkiaRenderer {
- public:
-  VulkanSkiaRenderer(const viz::RendererSettings* settings,
-                     viz::OutputSurface* output_surface,
-                     viz::DisplayResourceProvider* resource_provider,
-                     viz::SkiaOutputSurface* skia_output_surface,
-                     DrawMode mode)
-      : SkiaRenderer(settings,
-                     output_surface,
-                     resource_provider,
-                     skia_output_surface,
-                     mode) {}
-};
-
-class VulkanSkiaRendererWithFlippedSurface : public viz::SkiaRenderer {
- public:
-  VulkanSkiaRendererWithFlippedSurface(
-      const viz::RendererSettings* settings,
-      viz::OutputSurface* output_surface,
-      viz::DisplayResourceProvider* resource_provider,
-      viz::SkiaOutputSurface* skia_output_surface,
-      DrawMode mode)
-      : SkiaRenderer(settings,
-                     output_surface,
-                     resource_provider,
-                     skia_output_surface,
-                     mode) {}
-};
-
 template <>
 inline void RendererPixelTest<viz::GLRenderer>::SetUp() {
   SetUpGLRenderer(false);
@@ -263,26 +234,17 @@
 
 template <>
 inline void RendererPixelTest<viz::SkiaRenderer>::SetUp() {
-  SetUpSkiaRenderer(false, false);
+  SetUpSkiaRenderer(false);
 }
 
 template <>
 inline void RendererPixelTest<SkiaRendererWithFlippedSurface>::SetUp() {
-  SetUpSkiaRenderer(true, false);
-}
-
-template <>
-inline void RendererPixelTest<VulkanSkiaRenderer>::SetUp() {
-  SetUpSkiaRenderer(false, true);
-}
-
-template <>
-inline void RendererPixelTest<VulkanSkiaRendererWithFlippedSurface>::SetUp() {
-  SetUpSkiaRenderer(true, true);
+  SetUpSkiaRenderer(true);
 }
 
 typedef RendererPixelTest<viz::GLRenderer> GLRendererPixelTest;
 typedef RendererPixelTest<viz::SoftwareRenderer> SoftwareRendererPixelTest;
+typedef RendererPixelTest<viz::SkiaRenderer> SkiaRendererPixelTest;
 
 }  // namespace cc
 
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
index 4210796..93cfbd3 100644
--- a/chrome/android/chrome_java_sources.gni
+++ b/chrome/android/chrome_java_sources.gni
@@ -1359,6 +1359,8 @@
   "java/src/org/chromium/chrome/browser/searchwidget/SearchActivityLocationBarLayout.java",
   "java/src/org/chromium/chrome/browser/searchwidget/SearchBoxDataProvider.java",
   "java/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProvider.java",
+  "java/src/org/chromium/chrome/browser/send_tab_to_self/DevicePickerBottomSheetAdapter.java",
+  "java/src/org/chromium/chrome/browser/send_tab_to_self/DevicePickerBottomSheetContent.java",
   "java/src/org/chromium/chrome/browser/send_tab_to_self/NotificationManager.java",
   "java/src/org/chromium/chrome/browser/send_tab_to_self/NotificationSharedPrefManager.java",
   "java/src/org/chromium/chrome/browser/send_tab_to_self/SendTabToSelfAndroidBridge.java",
diff --git a/chrome/android/java/res/layout/send_tab_to_self_device_picker_item.xml b/chrome/android/java/res/layout/send_tab_to_self_device_picker_item.xml
new file mode 100644
index 0000000..d88e9a8c
--- /dev/null
+++ b/chrome/android/java/res/layout/send_tab_to_self_device_picker_item.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2019 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. -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:minHeight="56dp"
+    android:gravity="center_vertical"
+    android:orientation="horizontal"
+    android:paddingStart="10dp"
+    android:paddingEnd="10dp">
+        <org.chromium.ui.widget.ChromeImageView
+            android:id="@+id/device_icon"
+            android:layout_width="30dp"
+            android:layout_height="match_parent"
+            android:layout_weight="0.25"
+            android:layout_gravity="start"
+            android:gravity="center_vertical"/>
+        <TextView
+            android:id="@+id/device_name"
+            android:layout_width="100dp"
+            android:layout_height="0dp"
+            android:layout_weight="0.75"
+            android:gravity="center_vertical"
+            android:paddingStart="30dp"
+            android:paddingEnd="2dp"
+            android:maxLines="2"
+            android:ellipsize="end"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/chrome/android/java/res/layout/send_tab_to_self_device_picker_list.xml b/chrome/android/java/res/layout/send_tab_to_self_device_picker_list.xml
new file mode 100644
index 0000000..e94f742
--- /dev/null
+++ b/chrome/android/java/res/layout/send_tab_to_self_device_picker_list.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2019 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. -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:minHeight="56dp"
+    android:gravity="center_vertical"
+    android:orientation="vertical"
+    android:paddingStart="19dp"
+    android:paddingEnd="24dp">
+       <ListView
+        android:id="@+id/device_picker_list"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1" />
+</LinearLayout>
\ No newline at end of file
diff --git a/chrome/android/java/res/layout/send_tab_to_self_device_picker_toolbar.xml b/chrome/android/java/res/layout/send_tab_to_self_device_picker_toolbar.xml
new file mode 100644
index 0000000..78f6b744
--- /dev/null
+++ b/chrome/android/java/res/layout/send_tab_to_self_device_picker_toolbar.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2019 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. -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal"
+    android:gravity="center_vertical"
+    android:background="@android:color/white">
+        <TextView
+            android:id="@+id/device_picker_toolbar"
+            android:layout_width="match_parent"
+            android:layout_height="50dp"
+            android:gravity="center_vertical"
+            android:paddingStart="30dp"
+            android:paddingEnd="10dp"
+            android:paddingTop="8dp"
+            android:paddingBottom="8dp"
+            android:ellipsize="end"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/send_tab_to_self/DevicePickerBottomSheetAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/send_tab_to_self/DevicePickerBottomSheetAdapter.java
new file mode 100644
index 0000000..3cff738
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/send_tab_to_self/DevicePickerBottomSheetAdapter.java
@@ -0,0 +1,63 @@
+// Copyright 2019 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.
+
+package org.chromium.chrome.browser.send_tab_to_self;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+
+import org.chromium.base.ContextUtils;
+import org.chromium.chrome.R;
+import org.chromium.ui.widget.ChromeImageView;
+
+/**
+ * Adapter to populate the Target Device Picker sheet.
+ */
+public class DevicePickerBottomSheetAdapter extends BaseAdapter {
+    private final LayoutInflater mInflator;
+    private final Context mContext;
+
+    public DevicePickerBottomSheetAdapter() {
+        mContext = ContextUtils.getApplicationContext();
+        mInflator = LayoutInflater.from(mContext);
+    }
+
+    @Override
+    public int getCount() {
+        return 0;
+    }
+
+    @Override
+    public Object getItem(int position) {
+        return null;
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return position;
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        if (convertView == null) {
+            convertView =
+                    mInflator.inflate(R.layout.send_tab_to_self_device_picker_item, parent, false);
+
+            ChromeImageView deviceIcon = convertView.findViewById(R.id.device_icon);
+            /// TODO(crbug.com/949223): Populate with the right icon here.
+            // deviceIcon.setImageDrawable(
+            // AppCompatResources.getDrawable(mContext, R.drawable.ic_check_googblue_24dp));
+            deviceIcon.setVisibility(View.VISIBLE);
+
+            // TODO(crbug.com/949223): Populate the device name here.
+            // TextView deviceName = convertView.findViewById(R.id.device_name);
+            // deviceName.setText(getItem(position));
+            // TODO(crbug.com/949223): Add logic to handle click action
+        }
+        return convertView;
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/send_tab_to_self/DevicePickerBottomSheetContent.java b/chrome/android/java/src/org/chromium/chrome/browser/send_tab_to_self/DevicePickerBottomSheetContent.java
new file mode 100644
index 0000000..580b9c9
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/send_tab_to_self/DevicePickerBottomSheetContent.java
@@ -0,0 +1,125 @@
+// Copyright 2019 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.
+
+package org.chromium.chrome.browser.send_tab_to_self;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import org.chromium.chrome.R;
+import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet;
+import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet.BottomSheetContent;
+
+/**
+ * Bottom sheet content to display a list of devices a user can send a tab to after they have
+ * chosen to share it with themselves through the SendTabToSelfFeature.
+ */
+public class DevicePickerBottomSheetContent implements BottomSheetContent, OnItemClickListener {
+    Context mContext;
+    ChromeActivity mActivity;
+    ViewGroup mToolbarView;
+    ViewGroup mContentView;
+    DevicePickerBottomSheetAdapter mAdapter;
+
+    public DevicePickerBottomSheetContent(Context context, ChromeActivity activity) {
+        mContext = context;
+        mActivity = activity;
+        mAdapter = new DevicePickerBottomSheetAdapter();
+
+        createToolbarView();
+    }
+
+    private void createToolbarView() {
+        mToolbarView = (ViewGroup) LayoutInflater.from(mContext).inflate(
+                R.layout.send_tab_to_self_device_picker_toolbar, null);
+        TextView toolbarText = mToolbarView.findViewById(R.id.device_picker_toolbar);
+        toolbarText.setText(R.string.send_tab_to_self_sheet_toolbar);
+    }
+
+    private void createContentView() {
+        mContentView = (ViewGroup) LayoutInflater.from(mContext).inflate(
+                R.layout.send_tab_to_self_device_picker_list, null);
+        ListView listView = mContentView.findViewById(R.id.device_picker_list);
+
+        // Set the padding so that the toolbar is aligned with the list.
+        // TODO(tgupta): Figure out whether this can be incorporated directly in the definition of
+        // the list view rather than set programatically.
+        // listView.setPadding(0, convertDpToPx(80), 0, 0);
+        listView.setAdapter(mAdapter);
+        listView.setOnItemClickListener(this);
+    }
+
+    @Override
+    public View getContentView() {
+        return mContentView;
+    }
+
+    private int convertDpToPx(int inDp) {
+        float scale = mContext.getResources().getDisplayMetrics().density;
+        return (int) (inDp * scale + 0.5f);
+    }
+
+    @Override
+    public View getToolbarView() {
+        return mToolbarView;
+    }
+
+    @Override
+    public int getVerticalScrollOffset() {
+        return 0;
+    }
+
+    @Override
+    public void destroy() {}
+
+    @Override
+    public int getPriority() {
+        return BottomSheet.ContentPriority.HIGH;
+    }
+
+    @Override
+    public boolean swipeToDismissEnabled() {
+        // This ensures that the bottom sheet reappears after the first time. Otherwise, the
+        // second time that a user initiates a share, the bottom sheet does not re-appear.
+        return true;
+    }
+
+    @Override
+    public boolean isPeekStateEnabled() {
+        // Return false to ensure that the entire bottom sheet is shown.
+        return false;
+    }
+
+    @Override
+    public int getSheetContentDescriptionStringId() {
+        return R.string.send_tab_to_self_content_description;
+    }
+
+    @Override
+    public int getSheetHalfHeightAccessibilityStringId() {
+        return R.string.send_tab_to_self_sheet_half_height;
+    }
+
+    @Override
+    public int getSheetFullHeightAccessibilityStringId() {
+        return R.string.send_tab_to_self_sheet_full_height;
+    }
+
+    @Override
+    public int getSheetClosedAccessibilityStringId() {
+        return R.string.send_tab_to_self_sheet_closed;
+    }
+
+    @Override
+    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+        // TODO(crbug.com/949223): Add logic to support tapping on a device.
+    }
+}
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd
index 24a5d0a0..f7d18ba 100644
--- a/chrome/android/java/strings/android_chrome_strings.grd
+++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -3951,6 +3951,21 @@
       <message name="IDS_SEND_TAB_TO_SELF_INFOBAR_MESSAGE_URL" desc="Clickable text displayed as part of a URL in the inforbar displayed when a user receives a shared tab from another device.">
         Open
       </message>
+      <message name="IDS_SEND_TAB_TO_SELF_CONTENT_DESCRIPTION" desc="Content description for the target device picker.">
+        Device picker to share a tab with.
+      </message>
+      <message name="IDS_SEND_TAB_TO_SELF_SHEET_HALF_HEIGHT" desc="Accessibility string read when the target device picker sheet is opened at half height. The sheet will occupy the bottom half the screen.">
+        Device picker to share a tab with is opened at half height.
+      </message>
+      <message name="IDS_SEND_TAB_TO_SELF_SHEET_FULL_HEIGHT" desc="Accessibility string read when the target device picker sheet is opened at full height. The sheet will occupy the entire screen.">
+        Device picker to share a tab with is opened at full height.
+      </message>
+      <message name="IDS_SEND_TAB_TO_SELF_SHEET_CLOSED" desc="Accessibility string read when the target device picker sheet is closed.">
+        Device picker to share a tab with is closed.
+      </message>
+      <message name="IDS_SEND_TAB_TO_SELF_SHEET_TOOLBAR" desc="Header for device picker sheet where users can pick a device to send a tab to.">
+        Send to
+      </message>
 
       <!-- Chrome Duet -->
       <message name="IDS_IPH_DUET_TITLE" desc="This string appears in an overlay that explains a new UI to users. 'Search' refers to searching the web, and 'explore' refers to Chrome's suggested content.">
diff --git a/chrome/android/webapk/shell_apk/manifest/bound_manifest_config.json b/chrome/android/webapk/shell_apk/manifest/bound_manifest_config.json
index 0ba6f57..e371d8ba 100644
--- a/chrome/android/webapk/shell_apk/manifest/bound_manifest_config.json
+++ b/chrome/android/webapk/shell_apk/manifest/bound_manifest_config.json
@@ -22,19 +22,18 @@
   },
   "share_template": [{
 	  "index": "0",
-	  "title": "Share All",
+	  "title": "Share Text and Images",
 	  "action": "https://pwa.rocks/share.html",
+          "method": "POST",
+          "enctype": "multipart/form-data",
 	  "param_title": "title",
 	  "param_text": "text",
-	  "param_url": "url"
-  },
-  {
-	  "index": "1",
-	  "title": "Share Title",
-	  "action": "https://pwa.rocks/share_title.html",
-	  "param_title": "title",
-	  "param_text": "text",
-	  "param_url": "url"
+	  "param_url": "url",
+          "is_file_upload": true,
+          "param_names": "[&quot;param_name&quot;]",
+          "param_accepts": "[[&quot;image/*&quot;]]",
+          "mime_types": [{
+            "mime_type": "image/*"
+          }]
   }]
-
 }
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc
index a82dbf3..58e5cbb 100644
--- a/chrome/app/chrome_main_delegate.cc
+++ b/chrome/app/chrome_main_delegate.cc
@@ -574,7 +574,8 @@
     std::string process_type =
         command_line.GetSwitchValueASCII(switches::kProcessType);
     bool is_browser_process = process_type.empty();
-    gwp_asan::EnableForMalloc(is_canary_dev || is_browser_process);
+    gwp_asan::EnableForMalloc(is_canary_dev || is_browser_process,
+                              process_type.c_str());
   }
 #endif
 
@@ -583,7 +584,11 @@
     version_info::Channel channel = chrome::GetChannel();
     bool is_canary_dev = (channel == version_info::Channel::CANARY ||
                           channel == version_info::Channel::DEV);
-    gwp_asan::EnableForPartitionAlloc(is_canary_dev);
+    const base::CommandLine& command_line =
+        *base::CommandLine::ForCurrentProcess();
+    std::string process_type =
+        command_line.GetSwitchValueASCII(switches::kProcessType);
+    gwp_asan::EnableForPartitionAlloc(is_canary_dev, process_type.c_str());
   }
 #endif
 }
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index afeff761..9dd8d27 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -213,6 +213,18 @@
   <message name="IDS_CELLULAR_SETUP_TRY_AGAIN_LABEL" desc="Label for button to retry a step during cellular setup">
     Try again
   </message>
+  <message name="IDS_CELLULAR_SETUP_SIM_DETECT_PAGE_TITLE" desc="Title for first screen of cellular setup during which ChromeOS is preparing the cellular device for setup." translateable="false">
+    Sim Detect Page
+  </message>
+  <message name="IDS_CELLULAR_SETUP_PROVISIONING_PAGE_TITLE" desc="Title for cellular setup step in which the user uses the embedded carrier provisioning portal to make payment and activate the device." translateable="false">
+    Provisioning Page
+  </message>
+  <message name="IDS_CELLULAR_SETUP_SUCCESS_PAGE_TITLE" desc="Title for the final success screen of cellular setup that tells the user that setup is completed but service is being activated" translateable="false">
+    Success Page
+  </message>
+  <message name="IDS_CELLULAR_SETUP_SUCCESS_PAGE_MESSAGE" desc="Message displayed under title in final success screen of cellular setup that tells user that service may take a while to activate." translateable="false">
+    Setup Completed.
+  </message>
 
   <!-- Upgrade notifications -->
   <message name="IDS_RELAUNCH_REQUIRED_TITLE_DAYS" desc="The title of a dialog that tells users the device must be restarted within two or more days.">
@@ -2168,14 +2180,11 @@
   </message>
 
   <!-- EOL Notification Strings -->
-  <message name="IDS_EOL_NOTIFICATION_DISPLAY_SOURCE" desc="Notification header title shown to inform the user that this device is no longer supported.">
-    End of support
-  </message>
   <message name="IDS_EOL_NOTIFICATION_TITLE" desc="Notification title shown to inform the user that this device is no longer supported.">
-    This device is no longer supported
+    Final software update
   </message>
   <message name="IDS_EOL_NOTIFICATION_EOL" desc="Notification shown to inform the user that this device will no longer receive latest software updates.">
-    This device will no longer receive the latest software updates. Please consider upgrading.
+    This is the last automatic software and security update for this <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph>. To get future updates, upgrade to a newer model.
   </message>
   <message name="IDS_EOL_DISMISS_BUTTON" desc="A button label shown in the notification for eol status change to dismiss the notification.">
     Don't remind me again
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 00f84f1..1f1280e 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -3326,9 +3326,6 @@
         </message>
       </if>
 
-      <message name="IDS_UTILITY_PROCESS_PROXY_RESOLVER_NAME" desc="The name of the utility process used for out-of-process V8 proxy resolution.">
-        V8 Proxy Resolver
-      </message>
       <if expr="chromeos">
         <message name="IDS_UTILITY_PROCESS_CUPS_IPP_PARSER_SERVICE_NAME" desc="The name of the utility process used for parsing IPP requests out-of-process.">
           CUPS IPP Parser
@@ -8250,17 +8247,11 @@
         <message name="IDS_AUTO_SIGNIN_FIRST_RUN_OK" desc="The text of the OK button in the dialog during the autosign-in first run experience.">
           OK, Got It
         </message>
-        <message name="IDS_AUTO_SIGNIN_FIRST_RUN_TURN_OFF" desc="The text of the 'turn off' button in the dialog during the autosign-in first run experience.">
-          Turn Off
-        </message>
       </if>
       <if expr="not use_titlecase">
         <message name="IDS_AUTO_SIGNIN_FIRST_RUN_OK" desc="The text of the OK button in the dialog during the autosign-in first run experience.">
           OK, got it
         </message>
-        <message name="IDS_AUTO_SIGNIN_FIRST_RUN_TURN_OFF" desc="The text of the 'turn off' button in the dialog during the autosign-in first run experience.">
-          Turn off
-        </message>
       </if>
 
       <!-- Extra Mac UI Strings -->
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index d50f171..9ff87bb 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -2092,6 +2092,7 @@
     "//services/resource_coordinator/public/cpp:resource_coordinator_cpp",
     "//services/service_manager/public/cpp",
     "//services/shape_detection/public/mojom",
+    "//services/strings",
     "//skia",
     "//sql",
     "//storage/browser",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index c5390e0..5b8547f 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -89,6 +89,7 @@
   "+services/resource_coordinator/public/cpp",
   "+services/resource_coordinator/public/mojom",
   "+services/shape_detection/public/mojom",
+  "+services/strings",
   "+services/video_capture/public",
   "+services/viz/privileged",
   "+services/viz/public/interfaces",
diff --git a/chrome/browser/android/vr/vr_shell_delegate.cc b/chrome/browser/android/vr/vr_shell_delegate.cc
index 4db9a62..103c8c5d 100644
--- a/chrome/browser/android/vr/vr_shell_delegate.cc
+++ b/chrome/browser/android/vr/vr_shell_delegate.cc
@@ -136,13 +136,6 @@
     jint start_action) {
   VrStartAction action = static_cast<VrStartAction>(start_action);
 
-  if (action == VrStartAction::kDeepLinkedApp) {
-    // If this is a deep linked app we expect a DisplayActivate to be coming
-    // down the pipeline shortly.
-    possible_presentation_start_action_ =
-        PresentationStartAction::kDeepLinkedApp;
-  }
-
   if (!vr_shell_) {
     pending_vr_start_action_ = action;
     return;
@@ -212,15 +205,9 @@
                                       const JavaParamRef<jobject>& obj) {
   device::GvrDevice* gvr_device = GetGvrDevice();
   if (gvr_device) {
-    if (!possible_presentation_start_action_ ||
-        possible_presentation_start_action_ !=
-            PresentationStartAction::kDeepLinkedApp) {
-      // The only possible sources for DisplayActivate are at the moment DLAs
-      // and HeadsetActivations. Therefore if it's not a DLA it must be a
-      // HeadsetActivation.
-      possible_presentation_start_action_ =
-          PresentationStartAction::kHeadsetActivation;
-    }
+    // The only possible source for DisplayActivate is HeadsetActivation.
+    possible_presentation_start_action_ =
+        PresentationStartAction::kHeadsetActivation;
 
     gvr_device->Activate(
         device::mojom::VRDisplayEventReason::MOUNTED,
diff --git a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
index d6664fdf..78e6e33 100644
--- a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
+++ b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
@@ -313,6 +313,9 @@
 }
 
 void ChromeAutocompleteProviderClient::PrefetchImage(const GURL& url) {
+  // Note: Android uses different image fetching mechanism to avoid
+  // penalty of copying byte buffers from C++ to Java.
+#if !defined(OS_ANDROID)
   BitmapFetcherService* image_service =
       BitmapFetcherServiceFactory::GetForBrowserContext(profile_);
   DCHECK(image_service);
@@ -358,6 +361,7 @@
         })");
 
   image_service->Prefetch(url, traffic_annotation);
+#endif  // !defined(OS_ANDROID)
 }
 
 void ChromeAutocompleteProviderClient::StartServiceWorker(
diff --git a/chrome/browser/autocomplete/search_provider_unittest.cc b/chrome/browser/autocomplete/search_provider_unittest.cc
index 845df371..4035c309 100644
--- a/chrome/browser/autocomplete/search_provider_unittest.cc
+++ b/chrome/browser/autocomplete/search_provider_unittest.cc
@@ -2805,7 +2805,7 @@
 
 // Verifies that "http://" is not trimmed for input that is a leading substring.
 TEST_F(SearchProviderTest, NavigationInlineSchemeSubstring) {
-  const base::string16 input(ASCIIToUTF16("ht"));
+  const base::string16 input(ASCIIToUTF16("http:"));
   const base::string16 url(ASCIIToUTF16("http://a.com"));
   SearchSuggestionParser::NavigationResult result(
       ChromeAutocompleteSchemeClassifier(&profile_), GURL(url),
@@ -2817,7 +2817,7 @@
   QueryForInput(input, false, false);
   AutocompleteMatch match_inline(provider_->NavigationToMatch(result));
   EXPECT_EQ(url, match_inline.fill_into_edit);
-  EXPECT_EQ(url.substr(2), match_inline.inline_autocompletion);
+  EXPECT_EQ(url.substr(5), match_inline.inline_autocompletion);
   EXPECT_TRUE(match_inline.allowed_to_be_default_match);
   EXPECT_EQ(url, match_inline.contents);
 
@@ -2829,21 +2829,21 @@
   EXPECT_EQ(url, match_prevent.contents);
 }
 
-// Verifies that input "w" marks a more significant domain label than "www.".
+// Verifies that input "h" matches navsuggest "http://www.[h]ttp.com/http" and
+// "http://www." is trimmed.
 TEST_F(SearchProviderTest, NavigationInlineDomainClassify) {
-  QueryForInput(ASCIIToUTF16("w"), false, false);
+  QueryForInput(ASCIIToUTF16("h"), false, false);
   SearchSuggestionParser::NavigationResult result(
-      ChromeAutocompleteSchemeClassifier(&profile_), GURL("http://www.wow.com"),
-      AutocompleteMatchType::NAVSUGGEST, 0, base::string16(), std::string(),
-      false, 0, false, ASCIIToUTF16("w"));
+      ChromeAutocompleteSchemeClassifier(&profile_),
+      GURL("http://www.http.com/http"), AutocompleteMatchType::NAVSUGGEST, 0,
+      base::string16(), std::string(), false, 0, false, ASCIIToUTF16("h"));
   result.set_received_after_last_keystroke(false);
   AutocompleteMatch match(provider_->NavigationToMatch(result));
-  EXPECT_EQ(ASCIIToUTF16("ow.com"), match.inline_autocompletion);
+  EXPECT_EQ(ASCIIToUTF16("ttp.com/http"), match.inline_autocompletion);
   EXPECT_TRUE(match.allowed_to_be_default_match);
-  EXPECT_EQ(ASCIIToUTF16("www.wow.com"), match.fill_into_edit);
-  EXPECT_EQ(ASCIIToUTF16("wow.com"), match.contents);
+  EXPECT_EQ(ASCIIToUTF16("www.http.com/http"), match.fill_into_edit);
+  EXPECT_EQ(ASCIIToUTF16("http.com/http"), match.contents);
 
-  // Ensure that the match for input "w" is marked on "wow" and not "www".
   ASSERT_EQ(2U, match.contents_class.size());
   EXPECT_EQ(0U, match.contents_class[0].offset);
   EXPECT_EQ(AutocompleteMatch::ACMatchClassification::URL |
@@ -2854,6 +2854,67 @@
             match.contents_class[1].style);
 }
 
+// Verifies navsuggests prefer prefix matching even when a URL prefix prevents
+// the input from being a perfect prefix of the suggest text; e.g., the input
+// 'moon.com', matches 'http://[moon.com]/moon' and the 2nd 'moon' is unmatched.
+TEST_F(SearchProviderTest, NavigationPrefixClassify) {
+  QueryForInput(ASCIIToUTF16("moon"), false, false);
+  SearchSuggestionParser::NavigationResult result(
+      ChromeAutocompleteSchemeClassifier(&profile_),
+      GURL("http://moon.com/moon"), AutocompleteMatchType::NAVSUGGEST, 0,
+      base::string16(), std::string(), false, 0, false, ASCIIToUTF16("moon"));
+  result.set_received_after_last_keystroke(false);
+  AutocompleteMatch match(provider_->NavigationToMatch(result));
+  EXPECT_EQ(ASCIIToUTF16("moon.com/moon"), match.contents);
+  ASSERT_EQ(2U, match.contents_class.size());
+  EXPECT_EQ(0U, match.contents_class[0].offset);
+  EXPECT_EQ(AutocompleteMatch::ACMatchClassification::MATCH |
+                AutocompleteMatch::ACMatchClassification::URL,
+            match.contents_class[0].style);
+  EXPECT_EQ(4U, match.contents_class[1].offset);
+  EXPECT_EQ(AutocompleteMatch::ACMatchClassification::URL,
+            match.contents_class[1].style);
+}
+
+// Verifies navsuggests prohibit mid-word matches; e.g., 'f[acebook].com'.
+TEST_F(SearchProviderTest, NavigationMidWordClassify) {
+  QueryForInput(ASCIIToUTF16("acebook"), false, false);
+  SearchSuggestionParser::NavigationResult result(
+      ChromeAutocompleteSchemeClassifier(&profile_),
+      GURL("http://www.facebook.com"), AutocompleteMatchType::NAVSUGGEST, 0,
+      base::string16(), std::string(), false, 0, false,
+      ASCIIToUTF16("acebook"));
+  result.set_received_after_last_keystroke(false);
+  AutocompleteMatch match(provider_->NavigationToMatch(result));
+  EXPECT_EQ(ASCIIToUTF16("facebook.com"), match.contents);
+  ASSERT_EQ(1U, match.contents_class.size());
+  EXPECT_EQ(0U, match.contents_class[0].offset);
+  EXPECT_EQ(AutocompleteMatch::ACMatchClassification::URL,
+            match.contents_class[0].style);
+}
+
+// Verifies navsuggests break user and suggest texts on words;
+// e.g., the input 'duck', matches 'yellow-animals.com/[duck]'
+TEST_F(SearchProviderTest, NavigationWordBreakClassify) {
+  QueryForInput(ASCIIToUTF16("duck"), false, false);
+  SearchSuggestionParser::NavigationResult result(
+      ChromeAutocompleteSchemeClassifier(&profile_),
+      GURL("http://www.yellow-animals.com/duck"),
+      AutocompleteMatchType::NAVSUGGEST, 0, base::string16(), std::string(),
+      false, 0, false, ASCIIToUTF16("duck"));
+  result.set_received_after_last_keystroke(false);
+  AutocompleteMatch match(provider_->NavigationToMatch(result));
+  EXPECT_EQ(ASCIIToUTF16("yellow-animals.com/duck"), match.contents);
+  ASSERT_EQ(2U, match.contents_class.size());
+  EXPECT_EQ(0U, match.contents_class[0].offset);
+  EXPECT_EQ(AutocompleteMatch::ACMatchClassification::URL,
+            match.contents_class[0].style);
+  EXPECT_EQ(19U, match.contents_class[1].offset);
+  EXPECT_EQ(AutocompleteMatch::ACMatchClassification::MATCH |
+                AutocompleteMatch::ACMatchClassification::URL,
+            match.contents_class[1].style);
+}
+
 // Verifies that "http://" is trimmed in the general case.
 TEST_F(SearchProviderTest, DoTrimHttpScheme) {
   const base::string16 input(ASCIIToUTF16("face book"));
diff --git a/chrome/browser/banners/app_banner_manager.cc b/chrome/browser/banners/app_banner_manager.cc
index 0b7b2df..c475b05 100644
--- a/chrome/browser/banners/app_banner_manager.cc
+++ b/chrome/browser/banners/app_banner_manager.cc
@@ -210,10 +210,6 @@
   SendBannerPromptRequest();
 }
 
-base::WeakPtr<AppBannerManager> AppBannerManager::GetWeakPtr() {
-  return weak_factory_.GetWeakPtr();
-}
-
 void AppBannerManager::AddObserver(Observer* observer) {
   observer_list_.AddObserver(observer);
 }
@@ -233,8 +229,8 @@
       load_finished_(false),
       status_reporter_(std::make_unique<NullStatusReporter>()),
       install_animation_pending_(false),
-      installable_(Installable::UNKNOWN),
-      weak_factory_(this) {
+      installable_web_app_check_result_(
+          InstallableWebAppCheckResult::kUnknown) {
   DCHECK(manager_);
 
   AppBannerSettingsHelper::UpdateFromFieldTrial();
@@ -314,10 +310,10 @@
   manifest_url_ = data.manifest_url;
   manifest_ = *data.manifest;
 
-  PerformInstallableCheck();
+  PerformInstallableChecks();
 }
 
-InstallableParams AppBannerManager::ParamsToPerformInstallableCheck() {
+InstallableParams AppBannerManager::ParamsToPerformInstallableWebAppCheck() {
   InstallableParams params;
   params.valid_primary_icon = true;
   params.valid_manifest = true;
@@ -327,27 +323,32 @@
   return params;
 }
 
-void AppBannerManager::PerformInstallableCheck() {
+void AppBannerManager::PerformInstallableChecks() {
+  PerformInstallableWebAppCheck();
+}
+
+void AppBannerManager::PerformInstallableWebAppCheck() {
   if (!CheckIfShouldShowBanner())
     return;
 
   // Fetch and verify the other required information.
   UpdateState(State::PENDING_INSTALLABLE_CHECK);
   manager_->GetData(
-      ParamsToPerformInstallableCheck(),
-      base::BindOnce(&AppBannerManager::OnDidPerformInstallableCheck,
+      ParamsToPerformInstallableWebAppCheck(),
+      base::BindOnce(&AppBannerManager::OnDidPerformInstallableWebAppCheck,
                      GetWeakPtr()));
 }
 
-void AppBannerManager::OnDidPerformInstallableCheck(
+void AppBannerManager::OnDidPerformInstallableWebAppCheck(
     const InstallableData& data) {
   UpdateState(State::ACTIVE);
   if (data.has_worker && data.valid_manifest)
     TrackDisplayEvent(DISPLAY_EVENT_WEB_APP_BANNER_REQUESTED);
 
   auto error = data.errors.empty() ? NO_ERROR_DETECTED : data.errors[0];
-  SetInstallable(error == NO_ERROR_DETECTED ? Installable::INSTALLABLE_YES
-                                            : Installable::INSTALLABLE_NO);
+  SetInstallableWebAppCheckResult(error == NO_ERROR_DETECTED
+                                      ? InstallableWebAppCheckResult::kYes
+                                      : InstallableWebAppCheckResult::kNo);
 
   if (error != NO_ERROR_DETECTED) {
     if (error == NO_MATCHING_SERVICE_WORKER)
@@ -410,7 +411,7 @@
   manifest_ = blink::Manifest();
   manifest_url_ = GURL();
   validated_url_ = GURL();
-  SetInstallable(Installable::UNKNOWN);
+  SetInstallableWebAppCheckResult(InstallableWebAppCheckResult::kUnknown);
 }
 
 void AppBannerManager::Terminate() {
@@ -448,34 +449,36 @@
   return NO_ERROR_DETECTED;
 }
 
-bool AppBannerManager::IsInstallable() const {
-  return installable_ == Installable::INSTALLABLE_YES;
+bool AppBannerManager::IsInstallableWebApp() const {
+  return installable_web_app_check_result_ ==
+         InstallableWebAppCheckResult::kYes;
 }
 
-void AppBannerManager::SetInstallable(Installable installable) {
-  if (installable_ == installable)
+void AppBannerManager::SetInstallableWebAppCheckResult(
+    InstallableWebAppCheckResult result) {
+  if (installable_web_app_check_result_ == result)
     return;
 
-  installable_ = installable;
+  installable_web_app_check_result_ = result;
 
-  switch (installable) {
-    case Installable::UNKNOWN:
+  switch (result) {
+    case InstallableWebAppCheckResult::kUnknown:
       break;
-    case Installable::INSTALLABLE_YES:
-      last_installable_scope_ = manifest_.scope;
-      DCHECK(!last_installable_scope_.is_empty());
+    case InstallableWebAppCheckResult::kYes:
+      last_installable_web_app_scope_ = manifest_.scope;
+      DCHECK(!last_installable_web_app_scope_.is_empty());
       install_animation_pending_ =
           AppBannerSettingsHelper::CanShowInstallTextAnimation(
-              web_contents(), last_installable_scope_);
+              web_contents(), last_installable_web_app_scope_);
       break;
-    case Installable::INSTALLABLE_NO:
-      last_installable_scope_ = GURL();
+    case InstallableWebAppCheckResult::kNo:
+      last_installable_web_app_scope_ = GURL();
       install_animation_pending_ = false;
       break;
   }
 
   for (Observer& observer : observer_list_)
-    observer.OnInstallabilityUpdated();
+    observer.OnInstallableWebAppStatusUpdated();
 }
 
 void AppBannerManager::MigrateObserverListForTesting(
@@ -491,9 +494,10 @@
 void AppBannerManager::Stop(InstallableStatusCode code) {
   ReportStatus(code);
 
-  if (installable_ == Installable::UNKNOWN)
-    SetInstallable(Installable::INSTALLABLE_NO);
-  weak_factory_.InvalidateWeakPtrs();
+  if (installable_web_app_check_result_ ==
+      InstallableWebAppCheckResult::kUnknown)
+    SetInstallableWebAppCheckResult(InstallableWebAppCheckResult::kNo);
+  InvalidateWeakPtrs();
   ResetBindings();
   UpdateState(State::COMPLETE);
   status_reporter_ = std::make_unique<NullStatusReporter>(),
@@ -634,30 +638,31 @@
 }
 
 // static
-base::string16 AppBannerManager::GetInstallableAppName(
+base::string16 AppBannerManager::GetInstallableWebAppName(
     content::WebContents* web_contents) {
   AppBannerManager* manager = FromWebContents(web_contents);
-  if (!manager || !manager->IsInstallable())
+  if (!manager || !manager->IsInstallableWebApp())
     return base::string16();
   return manager->GetAppName();
 }
 
-bool AppBannerManager::IsProbablyInstallable() const {
-  if (IsInstallable())
+bool AppBannerManager::IsProbablyInstallableWebApp() const {
+  if (IsInstallableWebApp())
     return true;
-  return installable_ == Installable::UNKNOWN &&
-         last_installable_scope_.is_valid() &&
+  return installable_web_app_check_result_ ==
+             InstallableWebAppCheckResult::kUnknown &&
+         last_installable_web_app_scope_.is_valid() &&
          base::StartsWith(web_contents()->GetLastCommittedURL().spec(),
-                          last_installable_scope_.spec(),
+                          last_installable_web_app_scope_.spec(),
                           base::CompareCase::SENSITIVE);
 }
 
 bool AppBannerManager::MaybeConsumeInstallAnimation() {
-  DCHECK(IsProbablyInstallable());
+  DCHECK(IsProbablyInstallableWebApp());
   if (!install_animation_pending_)
     return false;
   AppBannerSettingsHelper::RecordInstallTextAnimationShown(
-      web_contents(), last_installable_scope_);
+      web_contents(), last_installable_web_app_scope_);
   install_animation_pending_ = false;
   return true;
 }
diff --git a/chrome/browser/banners/app_banner_manager.h b/chrome/browser/banners/app_banner_manager.h
index 8feea882..c1d1e1e 100644
--- a/chrome/browser/banners/app_banner_manager.h
+++ b/chrome/browser/banners/app_banner_manager.h
@@ -15,7 +15,6 @@
 #include "base/scoped_observer.h"
 #include "base/strings/string16.h"
 #include "chrome/browser/engagement/site_engagement_observer.h"
-#include "chrome/browser/installable/installable_ambient_badge_infobar_delegate.h"
 #include "chrome/browser/installable/installable_logging.h"
 #include "chrome/browser/installable/installable_manager.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
@@ -35,12 +34,6 @@
 class WebContents;
 }  // namespace content
 
-// This forward declaration exists solely for the DidFinishCreatingWebApp
-// callback, implemented and called on desktop platforms only.
-namespace web_app {
-enum class InstallResultCode;
-}
-
 namespace banners {
 
 // Coordinates the creation of an app banner, from detecting eligibility to
@@ -48,10 +41,6 @@
 // banner using the web app manifest. One web/native app may occupy the pipeline
 // at a time; navigation resets the manager and discards any work in progress.
 //
-// This class contains the generic functionality shared between all platforms,
-// as well as no-op callbacks that the platform-specific implementations pass to
-// base::Bind. This allows a WeakPtrFactory to be housed in this class.
-//
 // The InstallableManager fetches and validates whether a site is eligible for
 // banners. The manager is first called to fetch the manifest, so we can verify
 // whether the site is already installed (and on Android, divert the flow to a
@@ -59,7 +48,6 @@
 // web app banner (checking manifest validity, service worker, and icon).
 class AppBannerManager : public content::WebContentsObserver,
                          public blink::mojom::AppBannerService,
-                         public InstallableAmbientBadgeInfoBarDelegate::Client,
                          public SiteEngagementObserver {
  public:
   class Observer : public base::CheckedObserver {
@@ -69,7 +57,7 @@
 
     void ObserveAppBannerManager(AppBannerManager* manager);
 
-    virtual void OnInstallabilityUpdated() = 0;
+    virtual void OnInstallableWebAppStatusUpdated() = 0;
 
    private:
     ScopedObserver<AppBannerManager, Observer> scoped_observer_{this};
@@ -119,7 +107,7 @@
 
   // Installable describes whether a site satisifes the installablity
   // requirements.
-  enum class Installable { INSTALLABLE_YES, INSTALLABLE_NO, UNKNOWN };
+  enum class InstallableWebAppCheckResult { kUnknown, kNo, kYes };
 
   // Retrieves the platform specific instance of AppBannerManager from
   // |web_contents|.
@@ -140,13 +128,13 @@
 
   // Returns the app name if the current page is installable, otherwise returns
   // the empty string.
-  static base::string16 GetInstallableAppName(
+  static base::string16 GetInstallableWebAppName(
       content::WebContents* web_contents);
 
   // Returns whether installability checks have passed (e.g. having a service
   // worker fetch event) or have passed previously within the current manifest
   // scope.
-  bool IsProbablyInstallable() const;
+  bool IsProbablyInstallableWebApp() const;
 
   // Each successful installability check gets to show one animation prompt,
   // this returns and consumes the animation prompt if it is available.
@@ -167,34 +155,9 @@
   // Sends a message to the renderer that the user dismissed the banner.
   void SendBannerDismissed();
 
-  // Returns a WeakPtr to this object. Exposed so subclasses/infobars may
-  // may bind callbacks without needing their own WeakPtrFactory.
-  base::WeakPtr<AppBannerManager> GetWeakPtr();
-
   void AddObserver(Observer* observer);
   void RemoveObserver(Observer* observer);
 
-  // Overridden on desktop platforms. Called to initiate the web app
-  // install. Not used on Android.
-  virtual void CreateWebApp(WebappInstallSource install_source) {}
-
-  // Overridden and passed through base::Bind on desktop platforms. Called when
-  // the web app install initiated by a banner has completed. Not used on
-  // Android.
-  virtual void DidFinishCreatingWebApp(const web_app::AppId& app_id,
-                                       web_app::InstallResultCode code) {}
-
-  // Overridden and passed through base::Bind on Android. Called when the
-  // download of a native app's icon is complete, as native banners use an icon
-  // provided from the Play Store rather than the web manifest. Not used on
-  // desktop platforms.
-  virtual void OnAppIconFetched(const SkBitmap& bitmap) {}
-
-  // InstallableAmbientBadgeInfoBarDelegate::Client overrides. Further
-  // overridden on Android.
-  void AddToHomescreenFromBadge() override {}
-  void BadgeDismissed() override {}
-
  protected:
   explicit AppBannerManager(content::WebContents* web_contents);
   ~AppBannerManager() override;
@@ -219,6 +182,9 @@
   // alerting websites that a banner is about to be created.
   virtual std::string GetBannerType();
 
+  virtual base::WeakPtr<AppBannerManager> GetWeakPtr() = 0;
+  virtual void InvalidateWeakPtrs() = 0;
+
   // Returns true if |has_sufficient_engagement_| is true or
   // ShouldBypassEngagementChecks() returns true.
   bool HasSufficientEngagement() const;
@@ -226,7 +192,7 @@
   // Returns true if the kBypassAppBannerEngagementChecks flag is set.
   bool ShouldBypassEngagementChecks() const;
 
-  // Returns true if the webapp at |start_url| has already been installed, or
+  // Returns true if the web app at |start_url| has already been installed, or
   // should be considered installed. On Android, we rely on a heuristic that
   // may yield false negatives or false positives (crbug.com/786268).
   virtual bool IsWebAppConsideredInstalled(content::WebContents* web_contents,
@@ -240,18 +206,21 @@
 
   // Returns an InstallableParams object that requests all checks necessary for
   // a web app banner.
-  virtual InstallableParams ParamsToPerformInstallableCheck();
+  virtual InstallableParams ParamsToPerformInstallableWebAppCheck();
 
   // Run at the conclusion of OnDidGetManifest. For web app banners, this calls
   // back to the InstallableManager to continue checking criteria. For native
   // app banners, this checks whether native apps are preferred in the manifest,
   // and calls to Java to verify native app details. If a native banner isn't or
   // can't be requested, it continues with the web app banner checks.
-  virtual void PerformInstallableCheck();
+  virtual void PerformInstallableChecks();
+
+  virtual void PerformInstallableWebAppCheck();
 
   // Callback invoked by the InstallableManager once it has finished checking
   // all other installable properties.
-  virtual void OnDidPerformInstallableCheck(const InstallableData& result);
+  virtual void OnDidPerformInstallableWebAppCheck(
+      const InstallableData& result);
 
   // Records that a banner was shown. The |event_name| corresponds to the RAPPOR
   // metric being recorded.
@@ -280,7 +249,7 @@
   void SendBannerPromptRequest();
 
   // Shows the ambient badge if the current page advertises a native app or is
-  // a PWA. By default this shows nothing, but platform-specific code might
+  // a web app. By default this shows nothing, but platform-specific code might
   // override this to show UI (e.g. on Android).
   virtual void MaybeShowAmbientBadge();
 
@@ -368,8 +337,8 @@
   // Returns a status code based on the current state, to log when terminating.
   InstallableStatusCode TerminationCode() const;
 
-  bool IsInstallable() const;
-  void SetInstallable(Installable installable);
+  bool IsInstallableWebApp() const;
+  void SetInstallableWebAppCheckResult(InstallableWebAppCheckResult result);
 
   // Fetches the data required to display a banner for the current page.
   InstallableManager* manager_;
@@ -390,19 +359,14 @@
 
   std::unique_ptr<StatusReporter> status_reporter_;
   bool install_animation_pending_;
-  Installable installable_;
+  InstallableWebAppCheckResult installable_web_app_check_result_;
 
   // The scope of the most recent installability check if successful otherwise
   // invalid.
-  GURL last_installable_scope_;
+  GURL last_installable_web_app_scope_;
 
   base::ObserverList<Observer, true> observer_list_;
 
-  // The concrete subclasses of this class are expected to have their lifetimes
-  // scoped to the WebContents which they are observing. This allows us to use
-  // weak pointers for callbacks.
-  base::WeakPtrFactory<AppBannerManager> weak_factory_;
-
   DISALLOW_COPY_AND_ASSIGN(AppBannerManager);
 };
 
diff --git a/chrome/browser/banners/app_banner_manager_android.cc b/chrome/browser/banners/app_banner_manager_android.cc
index 24bce35..678dafe 100644
--- a/chrome/browser/banners/app_banner_manager_android.cc
+++ b/chrome/browser/banners/app_banner_manager_android.cc
@@ -114,7 +114,8 @@
       web_contents(), primary_icon_url_,
       ShortcutHelper::GetIdealHomescreenIconSizeInPx(),
       ShortcutHelper::GetMinimumHomescreenIconSizeInPx(),
-      base::BindOnce(&AppBannerManager::OnAppIconFetched, GetWeakPtr()));
+      base::BindOnce(&AppBannerManagerAndroid::OnNativeAppIconFetched,
+                     weak_factory_.GetWeakPtr()));
 }
 
 void AppBannerManagerAndroid::RequestAppBanner(const GURL& validated_url) {
@@ -165,44 +166,31 @@
                                            start_url, manifest_url);
 }
 
-InstallableParams AppBannerManagerAndroid::ParamsToPerformInstallableCheck() {
+InstallableParams
+AppBannerManagerAndroid::ParamsToPerformInstallableWebAppCheck() {
   InstallableParams params =
-      AppBannerManager::ParamsToPerformInstallableCheck();
+      AppBannerManager::ParamsToPerformInstallableWebAppCheck();
   params.valid_badge_icon = can_install_webapk_;
 
   return params;
 }
 
-void AppBannerManagerAndroid::PerformInstallableCheck() {
-  // Check if the manifest prefers that we show a native app banner. If so, call
-  // to Java to verify the details.
-  if (manifest_.prefer_related_applications &&
-      manifest_.related_applications.size() &&
-      !java_banner_manager_.is_null()) {
-    InstallableStatusCode code = NO_ERROR_DETECTED;
-    for (const auto& application : manifest_.related_applications) {
-      std::string platform = base::UTF16ToUTF8(application.platform.string());
-      std::string id = base::UTF16ToUTF8(application.id.string());
-      code = QueryNativeApp(platform, application.url, id);
-      if (code == NO_ERROR_DETECTED)
-        return;
-    }
+void AppBannerManagerAndroid::PerformInstallableChecks() {
+  if (ShouldPerformInstallableNativeAppCheck())
+    PerformInstallableNativeAppCheck();
+  else
+    PerformInstallableWebAppCheck();
+}
 
-    // We must have some error in |code| if we reached this point, so report it.
-    Stop(code);
-    return;
-  }
-
+void AppBannerManagerAndroid::PerformInstallableWebAppCheck() {
   if (can_install_webapk_ && !AreWebManifestUrlsWebApkCompatible(manifest_)) {
     Stop(URL_NOT_SUPPORTED_FOR_WEBAPK);
     return;
   }
-
-  // No native app banner was requested. Continue checking for a web app banner.
-  AppBannerManager::PerformInstallableCheck();
+  AppBannerManager::PerformInstallableWebAppCheck();
 }
 
-void AppBannerManagerAndroid::OnDidPerformInstallableCheck(
+void AppBannerManagerAndroid::OnDidPerformInstallableWebAppCheck(
     const InstallableData& data) {
   if (data.badge_icon && !data.badge_icon->drawsNothing()) {
     DCHECK(!data.badge_icon_url.is_empty());
@@ -211,27 +199,7 @@
     badge_icon_ = *data.badge_icon;
   }
 
-  AppBannerManager::OnDidPerformInstallableCheck(data);
-}
-
-void AppBannerManagerAndroid::OnAppIconFetched(const SkBitmap& bitmap) {
-  if (bitmap.drawsNothing()) {
-    Stop(NO_ICON_AVAILABLE);
-    return;
-  }
-
-  primary_icon_ = bitmap;
-
-  // If we triggered the installability check on page load, then it's possible
-  // we don't have enough engagement yet. If that's the case, return here but
-  // don't call Terminate(). We wait for OnEngagementEvent to tell us that we
-  // should trigger.
-  if (!HasSufficientEngagement()) {
-    UpdateState(State::PENDING_ENGAGEMENT);
-    return;
-  }
-
-  SendBannerPromptRequest();
+  AppBannerManager::OnDidPerformInstallableWebAppCheck(data);
 }
 
 void AppBannerManagerAndroid::ResetCurrentPageData() {
@@ -247,13 +215,13 @@
 
   if (native_app_data_.is_null()) {
     ui_delegate_ = AppBannerUiDelegateAndroid::Create(
-        GetWeakPtr(),
+        weak_factory_.GetWeakPtr(),
         ShortcutHelper::CreateShortcutInfo(manifest_url_, manifest_,
                                            primary_icon_url_, badge_icon_url_),
         primary_icon_, badge_icon_, install_source, can_install_webapk_);
   } else {
     ui_delegate_ = AppBannerUiDelegateAndroid::Create(
-        GetWeakPtr(), native_app_title_,
+        weak_factory_.GetWeakPtr(), native_app_title_,
         base::android::ScopedJavaLocalRef<jobject>(native_app_data_),
         primary_icon_, native_app_package_);
   }
@@ -295,6 +263,27 @@
   return std::string();
 }
 
+bool AppBannerManagerAndroid::ShouldPerformInstallableNativeAppCheck() {
+  return manifest_.prefer_related_applications &&
+         manifest_.related_applications.size() &&
+         !java_banner_manager_.is_null();
+}
+
+void AppBannerManagerAndroid::PerformInstallableNativeAppCheck() {
+  DCHECK(ShouldPerformInstallableNativeAppCheck());
+  InstallableStatusCode code = NO_ERROR_DETECTED;
+  for (const auto& application : manifest_.related_applications) {
+    std::string platform = base::UTF16ToUTF8(application.platform.string());
+    std::string id = base::UTF16ToUTF8(application.id.string());
+    code = QueryNativeApp(platform, application.url, id);
+    if (code == NO_ERROR_DETECTED)
+      return;
+  }
+
+  // We must have some error in |code| if we reached this point, so report it.
+  Stop(code);
+}
+
 InstallableStatusCode AppBannerManagerAndroid::QueryNativeApp(
     const std::string& platform,
     const GURL& url,
@@ -335,6 +324,26 @@
   return NO_ERROR_DETECTED;
 }
 
+void AppBannerManagerAndroid::OnNativeAppIconFetched(const SkBitmap& bitmap) {
+  if (bitmap.drawsNothing()) {
+    Stop(NO_ICON_AVAILABLE);
+    return;
+  }
+
+  primary_icon_ = bitmap;
+
+  // If we triggered the installability check on page load, then it's possible
+  // we don't have enough engagement yet. If that's the case, return here but
+  // don't call Terminate(). We wait for OnEngagementEvent to tell us that we
+  // should trigger.
+  if (!HasSufficientEngagement()) {
+    UpdateState(State::PENDING_ENGAGEMENT);
+    return;
+  }
+
+  SendBannerPromptRequest();
+}
+
 base::string16 AppBannerManagerAndroid::GetAppName() const {
   if (native_app_data_.is_null()) {
     // Prefer the short name if it's available. It's guaranteed that at least
@@ -361,9 +370,9 @@
   InfoBarService* infobar_service =
       InfoBarService::FromWebContents(web_contents());
   if (GetVisibleAmbientBadgeInfoBar(infobar_service) == nullptr) {
-    InstallableAmbientBadgeInfoBarDelegate::Create(web_contents(), GetWeakPtr(),
-                                                   GetAppName(), primary_icon_,
-                                                   manifest_.start_url);
+    InstallableAmbientBadgeInfoBarDelegate::Create(
+        web_contents(), weak_factory_.GetWeakPtr(), GetAppName(), primary_icon_,
+        manifest_.start_url);
   }
 }
 
@@ -377,6 +386,14 @@
     infobar_service->RemoveInfoBar(ambient_badge_infobar);
 }
 
+base::WeakPtr<AppBannerManager> AppBannerManagerAndroid::GetWeakPtr() {
+  return weak_factory_.GetWeakPtr();
+}
+
+void AppBannerManagerAndroid::InvalidateWeakPtrs() {
+  weak_factory_.InvalidateWeakPtrs();
+}
+
 // static
 AppBannerManager* AppBannerManager::FromWebContents(
     content::WebContents* web_contents) {
diff --git a/chrome/browser/banners/app_banner_manager_android.h b/chrome/browser/banners/app_banner_manager_android.h
index d7f0edb..9e49e37 100644
--- a/chrome/browser/banners/app_banner_manager_android.h
+++ b/chrome/browser/banners/app_banner_manager_android.h
@@ -10,8 +10,10 @@
 
 #include "base/android/scoped_java_ref.h"
 #include "base/macros.h"
+#include "base/memory/weak_ptr.h"
 #include "base/strings/string16.h"
 #include "chrome/browser/banners/app_banner_manager.h"
+#include "chrome/browser/installable/installable_ambient_badge_infobar_delegate.h"
 #include "content/public/browser/web_contents_user_data.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "url/gurl.h"
@@ -41,6 +43,7 @@
 // together.
 class AppBannerManagerAndroid
     : public AppBannerManager,
+      public InstallableAmbientBadgeInfoBarDelegate::Client,
       public content::WebContentsUserData<AppBannerManagerAndroid> {
  public:
   explicit AppBannerManagerAndroid(content::WebContents* web_contents);
@@ -85,7 +88,7 @@
   // AppBannerManager overrides.
   void RequestAppBanner(const GURL& validated_url) override;
 
-  // InstallableAmbientBadgeInfoBarAndroid::Client overrides.
+  // InstallableAmbientBadgeInfoBarDelegate::Client overrides.
   void AddToHomescreenFromBadge() override;
   void BadgeDismissed() override;
 
@@ -97,13 +100,16 @@
                                    const GURL& validated_url,
                                    const GURL& start_url,
                                    const GURL& manifest_url) override;
-  InstallableParams ParamsToPerformInstallableCheck() override;
-  void PerformInstallableCheck() override;
-  void OnDidPerformInstallableCheck(const InstallableData& result) override;
-  void OnAppIconFetched(const SkBitmap& bitmap) override;
+  void PerformInstallableChecks() override;
+  InstallableParams ParamsToPerformInstallableWebAppCheck() override;
+  void PerformInstallableWebAppCheck() override;
+  void OnDidPerformInstallableWebAppCheck(
+      const InstallableData& result) override;
   void ResetCurrentPageData() override;
   void ShowBannerUi(WebappInstallSource install_source) override;
   void MaybeShowAmbientBadge() override;
+  base::WeakPtr<AppBannerManager> GetWeakPtr() override;
+  void InvalidateWeakPtrs() override;
 
  private:
   friend class content::WebContentsUserData<AppBannerManagerAndroid>;
@@ -115,6 +121,9 @@
   std::string ExtractQueryValueForName(const GURL& url,
                                        const std::string& name);
 
+  bool ShouldPerformInstallableNativeAppCheck();
+  void PerformInstallableNativeAppCheck();
+
   // Returns NO_ERROR_DETECTED if |platform|, |url|, and |id| are consistent and
   // can be used to query the Play Store for a native app. Otherwise returns the
   // error which prevents querying from taking place. The query may not
@@ -125,6 +134,11 @@
                                        const GURL& url,
                                        const std::string& id);
 
+  // Called when the download of a native app's icon is complete, as native
+  // banners use an icon provided from the Play Store rather than the web
+  // manifest.
+  void OnNativeAppIconFetched(const SkBitmap& bitmap);
+
   // Returns the appropriate app name based on whether we have a native/web app.
   base::string16 GetAppName() const override;
 
@@ -154,6 +168,8 @@
   // Whether WebAPKs can be installed.
   bool can_install_webapk_;
 
+  base::WeakPtrFactory<AppBannerManagerAndroid> weak_factory_{this};
+
   WEB_CONTENTS_USER_DATA_KEY_DECL();
 
   DISALLOW_COPY_AND_ASSIGN(AppBannerManagerAndroid);
diff --git a/chrome/browser/banners/app_banner_manager_browsertest.cc b/chrome/browser/banners/app_banner_manager_browsertest.cc
index f4f22b5..9e77b2f 100644
--- a/chrome/browser/banners/app_banner_manager_browsertest.cc
+++ b/chrome/browser/banners/app_banner_manager_browsertest.cc
@@ -111,6 +111,12 @@
     }
   }
 
+  base::WeakPtr<AppBannerManager> GetWeakPtr() override {
+    return weak_factory_.GetWeakPtr();
+  }
+
+  void InvalidateWeakPtrs() override { weak_factory_.InvalidateWeakPtrs(); }
+
  private:
   base::Closure on_done_;
 
@@ -121,6 +127,8 @@
   std::unique_ptr<bool> banner_shown_;
   std::unique_ptr<WebappInstallSource> install_source_;
 
+  base::WeakPtrFactory<AppBannerManagerTest> weak_factory_{this};
+
   DISALLOW_COPY_AND_ASSIGN(AppBannerManagerTest);
 };
 
diff --git a/chrome/browser/banners/app_banner_manager_desktop.cc b/chrome/browser/banners/app_banner_manager_desktop.cc
index d94560f..8e31410 100644
--- a/chrome/browser/banners/app_banner_manager_desktop.cc
+++ b/chrome/browser/banners/app_banner_manager_desktop.cc
@@ -43,45 +43,12 @@
 
 AppBannerManagerDesktop::~AppBannerManagerDesktop() { }
 
-void AppBannerManagerDesktop::CreateWebApp(WebappInstallSource install_source) {
-  content::WebContents* contents = web_contents();
-  DCHECK(contents);
-
-  // TODO(loyso): Take appropriate action if WebApps disabled for profile.
-  web_app::CreateWebAppFromManifest(
-      contents, install_source,
-      base::BindOnce(&AppBannerManager::DidFinishCreatingWebApp, GetWeakPtr()));
+base::WeakPtr<AppBannerManager> AppBannerManagerDesktop::GetWeakPtr() {
+  return weak_factory_.GetWeakPtr();
 }
 
-void AppBannerManagerDesktop::DidFinishCreatingWebApp(
-    const web_app::AppId& app_id,
-    web_app::InstallResultCode code) {
-  content::WebContents* contents = web_contents();
-  if (!contents)
-    return;
-
-  // BookmarkAppInstallManager returns kFailedUnknownReason for any error.
-  // We can't distinguish kUserInstallDeclined case so far.
-  // If kFailedUnknownReason, we assume that the confirmation dialog was
-  // cancelled. Alternatively, the web app installation may have failed, but
-  // we can't tell the difference here.
-  // TODO(crbug.com/789381): plumb through enough information to be able to
-  // distinguish between extension install failures and user-cancellations of
-  // the app install dialog.
-  if (code != web_app::InstallResultCode::kSuccess) {
-    SendBannerDismissed();
-    TrackUserResponse(USER_RESPONSE_WEB_APP_DISMISSED);
-    AppBannerSettingsHelper::RecordBannerDismissEvent(
-        contents, GetAppIdentifier(), AppBannerSettingsHelper::WEB);
-    return;
-  }
-
-  SendBannerAccepted();
-  AppBannerSettingsHelper::RecordBannerInstallEvent(
-      contents, GetAppIdentifier(), AppBannerSettingsHelper::WEB);
-
-  // OnInstall must be called last since it resets Mojo bindings.
-  OnInstall(false /* is_native app */, blink::kWebDisplayModeStandalone);
+void AppBannerManagerDesktop::InvalidateWeakPtrs() {
+  weak_factory_.InvalidateWeakPtrs();
 }
 
 bool AppBannerManagerDesktop::IsWebAppConsideredInstalled(
@@ -123,6 +90,48 @@
   AppBannerManager::OnEngagementEvent(web_contents, url, score, type);
 }
 
+void AppBannerManagerDesktop::CreateWebApp(WebappInstallSource install_source) {
+  content::WebContents* contents = web_contents();
+  DCHECK(contents);
+
+  // TODO(loyso): Take appropriate action if WebApps disabled for profile.
+  web_app::CreateWebAppFromManifest(
+      contents, install_source,
+      base::BindOnce(&AppBannerManagerDesktop::DidFinishCreatingWebApp,
+                     weak_factory_.GetWeakPtr()));
+}
+
+void AppBannerManagerDesktop::DidFinishCreatingWebApp(
+    const web_app::AppId& app_id,
+    web_app::InstallResultCode code) {
+  content::WebContents* contents = web_contents();
+  if (!contents)
+    return;
+
+  // BookmarkAppInstallManager returns kFailedUnknownReason for any error.
+  // We can't distinguish kUserInstallDeclined case so far.
+  // If kFailedUnknownReason, we assume that the confirmation dialog was
+  // cancelled. Alternatively, the web app installation may have failed, but
+  // we can't tell the difference here.
+  // TODO(crbug.com/789381): plumb through enough information to be able to
+  // distinguish between extension install failures and user-cancellations of
+  // the app install dialog.
+  if (code != web_app::InstallResultCode::kSuccess) {
+    SendBannerDismissed();
+    TrackUserResponse(USER_RESPONSE_WEB_APP_DISMISSED);
+    AppBannerSettingsHelper::RecordBannerDismissEvent(
+        contents, GetAppIdentifier(), AppBannerSettingsHelper::WEB);
+    return;
+  }
+
+  SendBannerAccepted();
+  AppBannerSettingsHelper::RecordBannerInstallEvent(
+      contents, GetAppIdentifier(), AppBannerSettingsHelper::WEB);
+
+  // OnInstall must be called last since it resets Mojo bindings.
+  OnInstall(false /* is_native app */, blink::kWebDisplayModeStandalone);
+}
+
 WEB_CONTENTS_USER_DATA_KEY_IMPL(AppBannerManagerDesktop)
 
 }  // namespace banners
diff --git a/chrome/browser/banners/app_banner_manager_desktop.h b/chrome/browser/banners/app_banner_manager_desktop.h
index b0202136..3bfe3b6 100644
--- a/chrome/browser/banners/app_banner_manager_desktop.h
+++ b/chrome/browser/banners/app_banner_manager_desktop.h
@@ -8,9 +8,14 @@
 #include <memory>
 
 #include "base/macros.h"
+#include "base/memory/weak_ptr.h"
 #include "chrome/browser/banners/app_banner_manager.h"
 #include "content/public/browser/web_contents_user_data.h"
 
+namespace web_app {
+enum class InstallResultCode;
+}
+
 namespace banners {
 
 // Manages web app banners for desktop platforms.
@@ -30,12 +35,16 @@
   explicit AppBannerManagerDesktop(content::WebContents* web_contents);
 
   // AppBannerManager overrides.
-  void CreateWebApp(WebappInstallSource install_source) override;
-  void DidFinishCreatingWebApp(const web_app::AppId& app_id,
-                               web_app::InstallResultCode code) override;
+  base::WeakPtr<AppBannerManager> GetWeakPtr() override;
+  void InvalidateWeakPtrs() override;
+
+  // Called when the web app install initiated by a banner has completed.
+  virtual void DidFinishCreatingWebApp(const web_app::AppId& app_id,
+                                       web_app::InstallResultCode code);
 
  private:
   friend class content::WebContentsUserData<AppBannerManagerDesktop>;
+  friend class FakeAppBannerManagerDesktop;
 
   // AppBannerManager overrides.
   bool IsWebAppConsideredInstalled(content::WebContents* web_contents,
@@ -54,6 +63,10 @@
                          double score,
                          SiteEngagementService::EngagementType type) override;
 
+  void CreateWebApp(WebappInstallSource install_source);
+
+  base::WeakPtrFactory<AppBannerManagerDesktop> weak_factory_{this};
+
   WEB_CONTENTS_USER_DATA_KEY_DECL();
 
   DISALLOW_COPY_AND_ASSIGN(AppBannerManagerDesktop);
diff --git a/chrome/browser/banners/test_app_banner_manager_desktop.cc b/chrome/browser/banners/test_app_banner_manager_desktop.cc
index 292b899f..051d853 100644
--- a/chrome/browser/banners/test_app_banner_manager_desktop.cc
+++ b/chrome/browser/banners/test_app_banner_manager_desktop.cc
@@ -57,9 +57,9 @@
   if (!result.errors.empty())
     SetInstallable(false);
 }
-void TestAppBannerManagerDesktop::OnDidPerformInstallableCheck(
+void TestAppBannerManagerDesktop::OnDidPerformInstallableWebAppCheck(
     const InstallableData& result) {
-  AppBannerManagerDesktop::OnDidPerformInstallableCheck(result);
+  AppBannerManagerDesktop::OnDidPerformInstallableWebAppCheck(result);
   SetInstallable(result.errors.empty());
 }
 
diff --git a/chrome/browser/banners/test_app_banner_manager_desktop.h b/chrome/browser/banners/test_app_banner_manager_desktop.h
index 9dc6208..29587a9a 100644
--- a/chrome/browser/banners/test_app_banner_manager_desktop.h
+++ b/chrome/browser/banners/test_app_banner_manager_desktop.h
@@ -34,7 +34,8 @@
 
   // AppBannerManager:
   void OnDidGetManifest(const InstallableData& result) override;
-  void OnDidPerformInstallableCheck(const InstallableData& result) override;
+  void OnDidPerformInstallableWebAppCheck(
+      const InstallableData& result) override;
   void ResetCurrentPageData() override;
 
  private:
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index ea83bd5a..8cfd4f53 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -349,6 +349,7 @@
 #include "services/service_manager/public/mojom/connector.mojom.h"
 #include "services/service_manager/sandbox/sandbox_type.h"
 #include "services/service_manager/sandbox/switches.h"
+#include "services/strings/grit/services_strings.h"
 #include "services/viz/public/interfaces/constants.mojom.h"
 #include "storage/browser/fileapi/external_mount_points.h"
 #include "third_party/blink/public/common/features.h"
@@ -3972,7 +3973,7 @@
 
   (*services)[proxy_resolver::mojom::kProxyResolverServiceName] =
       base::BindRepeating(&l10n_util::GetStringUTF16,
-                          IDS_UTILITY_PROCESS_PROXY_RESOLVER_NAME);
+                          IDS_PROXY_RESOLVER_DISPLAY_NAME);
 #endif
 
 #if BUILDFLAG(ENABLE_PRINTING) && defined(OS_CHROMEOS)
diff --git a/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service.cc b/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service.cc
index 63254a4f..c360b65 100644
--- a/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service.cc
+++ b/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service.cc
@@ -70,14 +70,6 @@
 
 }  // namespace
 
-struct ArcWallpaperService::WallpaperIdPair {
-  // ID of wallpaper image which can be obtaind by
-  // WallpaperResizer::GetImageId().
-  uint32_t image_id;
-  // ID of wallpaper generated in the container side.
-  int32_t android_id;
-};
-
 class ArcWallpaperService::DecodeRequest : public ImageDecoder::ImageRequest {
  public:
   DecodeRequest(ArcWallpaperService* service, int32_t android_id)
@@ -128,26 +120,15 @@
 ArcWallpaperService::ArcWallpaperService(content::BrowserContext* context,
                                          ArcBridgeService* bridge_service)
     : arc_bridge_service_(bridge_service),
-      decode_request_sender_(std::make_unique<DecodeRequestSenderImpl>()),
-      observer_binding_(this),
-      weak_ptr_factory_(this) {
+      decode_request_sender_(std::make_unique<DecodeRequestSenderImpl>()) {
   arc_bridge_service_->wallpaper()->SetHost(this);
-  arc_bridge_service_->wallpaper()->AddObserver(this);
 }
 
 ArcWallpaperService::~ArcWallpaperService() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  arc_bridge_service_->wallpaper()->RemoveObserver(this);
   arc_bridge_service_->wallpaper()->SetHost(nullptr);
 }
 
-void ArcWallpaperService::OnConnectionReady() {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  ash::mojom::WallpaperObserverAssociatedPtrInfo ptr_info;
-  observer_binding_.Bind(mojo::MakeRequest(&ptr_info));
-  WallpaperControllerClient::Get()->AddObserver(std::move(ptr_info));
-}
-
 void ArcWallpaperService::SetWallpaper(const std::vector<uint8_t>& data,
                                        int32_t wallpaper_id) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
@@ -175,35 +156,12 @@
 
 void ArcWallpaperService::GetWallpaper(GetWallpaperCallback callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  WallpaperControllerClient::Get()->GetWallpaperImage(
-      base::BindOnce(&ArcWallpaperService::OnGetWallpaperImageCallback,
-                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+  gfx::ImageSkia image = WallpaperControllerClient::Get()->GetWallpaperImage();
+  base::PostTaskWithTraitsAndReplyWithResult(
+      FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
+      base::BindOnce(&EncodeImagePng, image), std::move(callback));
 }
 
-void ArcWallpaperService::OnWallpaperChanged(uint32_t image_id) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
-  bool current_wallpaper_notified = false;
-  for (auto it = id_pairs_.begin(); it != id_pairs_.end();) {
-    int32_t const android_id = it->android_id;
-    if (it->image_id == image_id) {
-      current_wallpaper_notified = true;
-      it = id_pairs_.erase(it);
-      NotifyWallpaperChanged(android_id);
-    } else {
-      ++it;
-    }
-  }
-
-  if (!current_wallpaper_notified)
-    NotifyWallpaperChanged(-1);
-}
-
-void ArcWallpaperService::OnWallpaperColorsChanged(
-    const std::vector<SkColor>& prominent_colors) {}
-
-void ArcWallpaperService::OnWallpaperBlurChanged(bool blurred) {}
-
 void ArcWallpaperService::OnWallpaperDecoded(const gfx::ImageSkia& image,
                                              int32_t android_id) {
   const AccountId account_id =
@@ -211,11 +169,20 @@
   const std::string wallpaper_files_id =
       WallpaperControllerClient::Get()->GetFilesId(account_id);
 
-  WallpaperControllerClient::Get()->SetThirdPartyWallpaper(
+  const bool result = WallpaperControllerClient::Get()->SetThirdPartyWallpaper(
       account_id, wallpaper_files_id, kAndroidWallpaperFilename,
-      ash::WALLPAPER_LAYOUT_CENTER_CROPPED, image,
-      base::BindOnce(&ArcWallpaperService::OnSetThirdPartyWallpaperCallback,
-                     weak_ptr_factory_.GetWeakPtr(), android_id));
+      ash::WALLPAPER_LAYOUT_CENTER_CROPPED, image);
+
+  // Notify the Android side whether the request is going through or not.
+  if (result)
+    NotifyWallpaperChanged(android_id);
+  else
+    NotifyWallpaperChangedAndReset(android_id);
+
+  // TODO(crbug.com/618922): Register the wallpaper to Chrome OS wallpaper
+  // picker. Currently the new wallpaper does not appear there. The best way
+  // to make this happen seems to do the same things as wallpaper_api.cc and
+  // wallpaper_private_api.cc.
 }
 
 void ArcWallpaperService::NotifyWallpaperChanged(int android_id) {
@@ -236,26 +203,4 @@
   NotifyWallpaperChanged(-1);
 }
 
-void ArcWallpaperService::OnSetThirdPartyWallpaperCallback(int32_t android_id,
-                                                           bool allowed,
-                                                           uint32_t image_id) {
-  if (allowed)
-    id_pairs_.push_back({image_id, android_id});
-  else
-    NotifyWallpaperChangedAndReset(android_id);
-
-  // TODO(crbug.com/618922): Register the wallpaper to Chrome OS wallpaper
-  // picker. Currently the new wallpaper does not appear there. The best way
-  // to make this happen seems to do the same things as wallpaper_api.cc and
-  // wallpaper_private_api.cc.
-}
-
-void ArcWallpaperService::OnGetWallpaperImageCallback(
-    GetWallpaperCallback callback,
-    const gfx::ImageSkia& image) {
-  base::PostTaskWithTraitsAndReplyWithResult(
-      FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
-      base::BindOnce(&EncodeImagePng, image), std::move(callback));
-}
-
 }  // namespace arc
diff --git a/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service.h b/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service.h
index c6c8fe7..6f7e950 100644
--- a/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service.h
+++ b/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service.h
@@ -10,28 +10,25 @@
 #include <memory>
 #include <vector>
 
-#include "ash/public/interfaces/wallpaper.mojom.h"
 #include "base/macros.h"
-#include "base/memory/weak_ptr.h"
 #include "chrome/browser/image_decoder.h"
 #include "components/arc/common/wallpaper.mojom.h"
-#include "components/arc/session/connection_observer.h"
 #include "components/keyed_service/core/keyed_service.h"
-#include "mojo/public/cpp/bindings/associated_binding.h"
 
 namespace content {
 class BrowserContext;
 }  // namespace content
 
+namespace gfx {
+class ImageSkia;
+}  // namespace gfx
+
 namespace arc {
 
 class ArcBridgeService;
 
 // Lives on the UI thread.
-class ArcWallpaperService : public KeyedService,
-                            public ConnectionObserver<mojom::WallpaperInstance>,
-                            public mojom::WallpaperHost,
-                            public ash::mojom::WallpaperObserver {
+class ArcWallpaperService : public KeyedService, public mojom::WallpaperHost {
  public:
   // Returns singleton instance for the given BrowserContext,
   // or nullptr if the browser |context| is not allowed to use ARC.
@@ -42,21 +39,12 @@
                       ArcBridgeService* bridge_service);
   ~ArcWallpaperService() override;
 
-  // ConnectionObserver<mojom::WallpaperInstance> overrides.
-  void OnConnectionReady() override;
-
   // mojom::WallpaperHost overrides.
   void SetWallpaper(const std::vector<uint8_t>& data,
                     int32_t wallpaper_id) override;
   void SetDefaultWallpaper() override;
   void GetWallpaper(GetWallpaperCallback callback) override;
 
-  // ash::mojom::WallpaperObserver overrides.
-  void OnWallpaperChanged(uint32_t image_id) override;
-  void OnWallpaperColorsChanged(
-      const std::vector<SkColor>& prominent_colors) override;
-  void OnWallpaperBlurChanged(bool blurred) override;
-
   class DecodeRequestSender {
    public:
     virtual ~DecodeRequestSender();
@@ -75,7 +63,6 @@
   friend class TestApi;
   class AndroidIdStore;
   class DecodeRequest;
-  struct WallpaperIdPair;
 
   // Initiates a set wallpaper request to //ash.
   void OnWallpaperDecoded(const gfx::ImageSkia& image, int32_t android_id);
@@ -87,27 +74,10 @@
   // -1 to reset wallpaper cache at Android side.
   void NotifyWallpaperChangedAndReset(int android_id);
 
-  // If the wallpaper is allowed to be shown on screen, stores the |image_id|
-  // in order to track the wallpaper change later, otherwise notify the Android
-  // side immediately that the request is not going through.
-  void OnSetThirdPartyWallpaperCallback(int32_t android_id,
-                                        bool allowed,
-                                        uint32_t image_id);
-
-  // Initiates an encoding image request after getting the wallpaper image.
-  void OnGetWallpaperImageCallback(GetWallpaperCallback callback,
-                                   const gfx::ImageSkia& image);
-
   ArcBridgeService* const arc_bridge_service_;  // Owned by ArcServiceManager.
   std::unique_ptr<DecodeRequest> decode_request_;
-  std::vector<WallpaperIdPair> id_pairs_;
   std::unique_ptr<DecodeRequestSender> decode_request_sender_;
 
-  // The binding this instance uses to implement ash::mojom::WallpaperObserver.
-  mojo::AssociatedBinding<ash::mojom::WallpaperObserver> observer_binding_;
-
-  base::WeakPtrFactory<ArcWallpaperService> weak_ptr_factory_;
-
   DISALLOW_COPY_AND_ASSIGN(ArcWallpaperService);
 };
 
diff --git a/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service_unittest.cc b/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service_unittest.cc
index 7e53975..8b84c4e 100644
--- a/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service_unittest.cc
+++ b/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service_unittest.cc
@@ -84,8 +84,7 @@
     // Wallpaper
     wallpaper_controller_client_ =
         std::make_unique<WallpaperControllerClient>();
-    wallpaper_controller_client_->InitForTesting(
-        test_wallpaper_controller_.CreateInterfacePtr());
+    wallpaper_controller_client_->InitForTesting(&test_wallpaper_controller_);
 
     // Arc services
     arc_service_manager_.set_browser_context(&testing_profile_);
@@ -136,7 +135,6 @@
 TEST_F(ArcWallpaperServiceTest, SetDefaultWallpaper) {
   test_wallpaper_controller_.ClearCounts();
   service_->SetDefaultWallpaper();
-  wallpaper_controller_client_->FlushForTesting();
   EXPECT_EQ(1, test_wallpaper_controller_.set_default_wallpaper_count());
 }
 
@@ -145,7 +143,6 @@
       std::make_unique<SuccessDecodeRequestSender>());
   std::vector<uint8_t> bytes;
   service_->SetWallpaper(bytes, 10 /*wallpaper_id=*/);
-  wallpaper_controller_client_->FlushForTesting();
   ASSERT_EQ(1u, wallpaper_instance_->changed_ids().size());
   EXPECT_EQ(10, wallpaper_instance_->changed_ids()[0]);
 
@@ -153,7 +150,6 @@
       base::BindOnce([](std::vector<uint8_t>* out,
                         const std::vector<uint8_t>& bytes) { *out = bytes; },
                      &bytes));
-  wallpaper_controller_client_->FlushForTesting();
   content::RunAllTasksUntilIdle();
   ASSERT_NE(0u, bytes.size());
 }
@@ -163,7 +159,6 @@
       std::make_unique<FailureDecodeRequestSender>());
   std::vector<uint8_t> bytes;
   service_->SetWallpaper(bytes, 10 /*wallpaper_id=*/);
-  wallpaper_controller_client_->FlushForTesting();
 
   // For failure case, ArcWallpaperService reports that wallpaper is changed to
   // requested wallpaper (ID=10), then reports that the wallpaper is changed
diff --git a/chrome/browser/chromeos/customization/customization_wallpaper_downloader_browsertest.cc b/chrome/browser/chromeos/customization/customization_wallpaper_downloader_browsertest.cc
index 19c4370..8017981 100644
--- a/chrome/browser/chromeos/customization/customization_wallpaper_downloader_browsertest.cc
+++ b/chrome/browser/chromeos/customization/customization_wallpaper_downloader_browsertest.cc
@@ -6,7 +6,7 @@
 
 #include <vector>
 
-#include "ash/public/interfaces/wallpaper.mojom.h"
+#include "ash/public/cpp/wallpaper_controller_observer.h"
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/macros.h"
@@ -20,7 +20,6 @@
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chromeos/constants/chromeos_switches.h"
-#include "mojo/public/cpp/bindings/associated_binding.h"
 #include "net/http/http_response_headers.h"
 #include "net/http/http_status_code.h"
 #include "net/test/embedded_test_server/http_response.h"
@@ -121,27 +120,22 @@
   return true;
 }
 
-class TestWallpaperObserver : public ash::mojom::WallpaperObserver {
+class TestWallpaperObserver : public ash::WallpaperControllerObserver {
  public:
-  TestWallpaperObserver() : finished_(false), observer_binding_(this) {
-    ash::mojom::WallpaperObserverAssociatedPtrInfo ptr_info;
-    observer_binding_.Bind(mojo::MakeRequest(&ptr_info));
-    WallpaperControllerClient::Get()->AddObserver(std::move(ptr_info));
+  TestWallpaperObserver() {
+    WallpaperControllerClient::Get()->AddObserver(this);
   }
 
-  ~TestWallpaperObserver() override = default;
+  ~TestWallpaperObserver() override {
+    WallpaperControllerClient::Get()->RemoveObserver(this);
+  }
 
-  // ash::mojom::WallpaperObserver:
-  void OnWallpaperChanged(uint32_t image_id) override {
+  // ash::WallpaperControllerObserver:
+  void OnWallpaperChanged() override {
     finished_ = true;
     base::RunLoop::QuitCurrentWhenIdleDeprecated();
   }
 
-  void OnWallpaperColorsChanged(
-      const std::vector<SkColor>& prominent_colors) override {}
-
-  void OnWallpaperBlurChanged(bool blurred) override {}
-
   // Wait until the wallpaper update is completed.
   void WaitForWallpaperChanged() {
     while (!finished_)
@@ -151,10 +145,7 @@
   void Reset() { finished_ = false; }
 
  private:
-  bool finished_;
-
-  // The binding this instance uses to implement ash::mojom::WallpaperObserver.
-  mojo::AssociatedBinding<ash::mojom::WallpaperObserver> observer_binding_;
+  bool finished_ = false;
 
   DISALLOW_COPY_AND_ASSIGN(TestWallpaperObserver);
 };
@@ -263,13 +254,8 @@
 
   // Verify the customized default wallpaper has replaced the built-in default
   // wallpaper.
-  base::RunLoop run_loop;
-  WallpaperControllerClient::Get()->GetWallpaperImage(
-      base::BindLambdaForTesting([&run_loop](const gfx::ImageSkia& image) {
-        run_loop.Quit();
-        EXPECT_TRUE(ImageIsNearColor(image, kCustomizedDefaultWallpaperColor));
-      }));
-  run_loop.Run();
+  gfx::ImageSkia image = WallpaperControllerClient::Get()->GetWallpaperImage();
+  EXPECT_TRUE(ImageIsNearColor(image, kCustomizedDefaultWallpaperColor));
   EXPECT_EQ(1U, num_attempts());
 }
 
@@ -295,13 +281,8 @@
 
   // Verify the customized default wallpaper has replaced the built-in default
   // wallpaper.
-  base::RunLoop run_loop;
-  WallpaperControllerClient::Get()->GetWallpaperImage(
-      base::BindLambdaForTesting([&run_loop](const gfx::ImageSkia& image) {
-        run_loop.Quit();
-        EXPECT_TRUE(ImageIsNearColor(image, kCustomizedDefaultWallpaperColor));
-      }));
-  run_loop.Run();
+  gfx::ImageSkia image = WallpaperControllerClient::Get()->GetWallpaperImage();
+  EXPECT_TRUE(ImageIsNearColor(image, kCustomizedDefaultWallpaperColor));
   EXPECT_EQ(2U, num_attempts());
 }
 
diff --git a/chrome/browser/chromeos/eol_notification.cc b/chrome/browser/chromeos/eol_notification.cc
index d0e0819..711958f 100644
--- a/chrome/browser/chromeos/eol_notification.cc
+++ b/chrome/browser/chromeos/eol_notification.cc
@@ -21,6 +21,7 @@
 #include "components/prefs/pref_service.h"
 #include "components/strings/grit/components_strings.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/chromeos/devicetype_utils.h"
 #include "ui/gfx/color_palette.h"
 #include "ui/gfx/paint_vector_icon.h"
 #include "ui/message_center/public/cpp/notification.h"
@@ -148,15 +149,15 @@
       ash::CreateSystemNotification(
           message_center::NOTIFICATION_TYPE_SIMPLE, kEolNotificationId,
           GetStringUTF16(IDS_EOL_NOTIFICATION_TITLE),
-          GetStringUTF16(IDS_EOL_NOTIFICATION_EOL),
-          GetStringUTF16(IDS_EOL_NOTIFICATION_DISPLAY_SOURCE),
-          GURL(kEolNotificationId),
+          l10n_util::GetStringFUTF16(IDS_EOL_NOTIFICATION_EOL,
+                                     ui::GetChromeOSDeviceName()),
+          base::string16() /* display_source */, GURL(kEolNotificationId),
           message_center::NotifierId(
               message_center::NotifierType::SYSTEM_COMPONENT,
               kEolNotificationId),
           data, new EolNotificationDelegate(profile_),
           ash::kNotificationEndOfSupportIcon,
-          message_center::SystemNotificationWarningLevel::CRITICAL_WARNING);
+          message_center::SystemNotificationWarningLevel::NORMAL);
 
   NotificationDisplayServiceFactory::GetForProfile(profile_)->Display(
       NotificationHandler::Type::TRANSIENT, *notification,
diff --git a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
index bc5b9ce7..0e856811 100644
--- a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
+++ b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
@@ -58,8 +58,6 @@
     wallpaper_private::SetCustomWallpaperLayout;
 namespace get_thumbnail = wallpaper_private::GetThumbnail;
 namespace save_thumbnail = wallpaper_private::SaveThumbnail;
-namespace get_offline_wallpaper_list =
-    wallpaper_private::GetOfflineWallpaperList;
 namespace record_wallpaper_uma = wallpaper_private::RecordWallpaperUMA;
 namespace get_collections_info = wallpaper_private::GetCollectionsInfo;
 namespace get_images_info = wallpaper_private::GetImagesInfo;
@@ -243,20 +241,12 @@
                   wallpaper_api_util::kCancelWallpaperMessage);
   dict->SetString("highResolutionSuffix", GetBackdropWallpaperSuffix());
 
-  WallpaperControllerClient::Get()->GetActiveUserWallpaperInfo(base::BindOnce(
-      &WallpaperPrivateGetStringsFunction::OnWallpaperInfoReturned, this,
-      std::move(dict)));
-  return RespondLater();
-}
-
-void WallpaperPrivateGetStringsFunction::OnWallpaperInfoReturned(
-    std::unique_ptr<base::DictionaryValue> dict,
-    const std::string& location,
-    ash::WallpaperLayout layout) {
-  dict->SetString("currentWallpaper", location);
+  auto info = WallpaperControllerClient::Get()->GetActiveUserWallpaperInfo();
+  dict->SetString("currentWallpaper", info.location);
   dict->SetString("currentWallpaperLayout",
-                  wallpaper_api_util::GetLayoutString(layout));
-  Respond(OneArgument(std::move(dict)));
+                  wallpaper_api_util::GetLayoutString(info.layout));
+
+  return RespondNow(OneArgument(std::move(dict)));
 }
 
 ExtensionFunction::ResponseAction
@@ -816,20 +806,12 @@
       get_current_wallpaper_thumbnail::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
 
-  WallpaperControllerClient::Get()->GetWallpaperImage(base::BindOnce(
-      &WallpaperPrivateGetCurrentWallpaperThumbnailFunction::
-          OnWallpaperImageReturned,
-      this, gfx::Size(params->thumbnail_width, params->thumbnail_height)));
-  return RespondLater();
-}
-
-void WallpaperPrivateGetCurrentWallpaperThumbnailFunction::
-    OnWallpaperImageReturned(const gfx::Size& thumbnail_size,
-                             const gfx::ImageSkia& image) {
+  auto image = WallpaperControllerClient::Get()->GetWallpaperImage();
+  gfx::Size thumbnail_size(params->thumbnail_width, params->thumbnail_height);
   image.EnsureRepsForSupportedScales();
   scoped_refptr<base::RefCountedBytes> thumbnail_data;
   GenerateThumbnail(image, thumbnail_size, &thumbnail_data);
-  Respond(OneArgument(std::make_unique<Value>(
+  return RespondNow(OneArgument(std::make_unique<Value>(
       Value::BlobStorage(thumbnail_data->front(),
                          thumbnail_data->front() + thumbnail_data->size()))));
 }
diff --git a/chrome/browser/chromeos/extensions/wallpaper_private_api.h b/chrome/browser/chromeos/extensions/wallpaper_private_api.h
index 50ddaee..5c2a757 100644
--- a/chrome/browser/chromeos/extensions/wallpaper_private_api.h
+++ b/chrome/browser/chromeos/extensions/wallpaper_private_api.h
@@ -31,12 +31,6 @@
 
   // ExtensionFunction:
   ResponseAction Run() override;
-
- private:
-  // Responds with the dictionary after getting the wallpaper info.
-  void OnWallpaperInfoReturned(std::unique_ptr<base::DictionaryValue> dict,
-                               const std::string& location,
-                               ash::WallpaperLayout layout);
 };
 
 // Check if sync themes setting is enabled.
@@ -417,10 +411,6 @@
   ResponseAction Run() override;
 
  private:
-  // Responds with the thumbnail data.
-  void OnWallpaperImageReturned(const gfx::Size& thumbnail_size,
-                                const gfx::ImageSkia& image);
-
   // WallpaperFunctionBase:
   void OnWallpaperDecoded(const gfx::ImageSkia& wallpaper) override;
 
diff --git a/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc b/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc
index 5c051c99..4f64fe0 100644
--- a/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc
+++ b/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc
@@ -71,7 +71,7 @@
   ScopedTestingLocalState local_state(TestingBrowserProcess::GetGlobal());
   WallpaperControllerClient client;
   TestWallpaperController test_controller;
-  client.InitForTesting(test_controller.CreateInterfacePtr());
+  client.InitForTesting(&test_controller);
   fake_user_manager()->AddUser(AccountId::FromUserEmail(kTestAccount));
 
   {
@@ -81,7 +81,6 @@
         extensions::api_test_utils::RunFunction(function.get(), "[]", nullptr));
   }
 
-  client.FlushForTesting();
   // Expect SetDefaultWallpaper() to be called exactly once.
   EXPECT_EQ(1, test_controller.set_default_wallpaper_count());
 }
diff --git a/chrome/browser/chromeos/login/demo_mode/demo_session_unittest.cc b/chrome/browser/chromeos/login/demo_mode/demo_session_unittest.cc
index c2a6cd3..338b7919 100644
--- a/chrome/browser/chromeos/login/demo_mode/demo_session_unittest.cc
+++ b/chrome/browser/chromeos/login/demo_mode/demo_session_unittest.cc
@@ -82,8 +82,7 @@
     session_manager_ = std::make_unique<session_manager::SessionManager>();
     wallpaper_controller_client_ =
         std::make_unique<WallpaperControllerClient>();
-    wallpaper_controller_client_->InitForTesting(
-        test_wallpaper_controller_.CreateInterfacePtr());
+    wallpaper_controller_client_->InitForTesting(&test_wallpaper_controller_);
   }
 
   void TearDown() override {
@@ -434,14 +433,12 @@
             test_wallpaper_controller_.remove_always_on_top_wallpaper_count());
   session_manager_->SetSessionState(
       session_manager::SessionState::LOGIN_PRIMARY);
-  wallpaper_controller_client_->FlushForTesting();
   EXPECT_EQ(0, test_wallpaper_controller_.show_always_on_top_wallpaper_count());
   EXPECT_EQ(0,
             test_wallpaper_controller_.remove_always_on_top_wallpaper_count());
 
   ASSERT_TRUE(FinishResourcesComponentLoad(
       base::FilePath(kTestDemoModeResourcesMountPoint)));
-  wallpaper_controller_client_->FlushForTesting();
   EXPECT_EQ(1, test_wallpaper_controller_.show_always_on_top_wallpaper_count());
   EXPECT_EQ(0,
             test_wallpaper_controller_.remove_always_on_top_wallpaper_count());
@@ -460,13 +457,11 @@
       profile, new ChromeAppDelegate(true /* keep_alive */),
       screensaver_app.get());
   demo_session->OnAppWindowActivated(app_window);
-  wallpaper_controller_client_->FlushForTesting();
   // The splash screen is not removed until active session starts.
   EXPECT_EQ(1, test_wallpaper_controller_.show_always_on_top_wallpaper_count());
   EXPECT_EQ(0,
             test_wallpaper_controller_.remove_always_on_top_wallpaper_count());
   session_manager_->SetSessionState(session_manager::SessionState::ACTIVE);
-  wallpaper_controller_client_->FlushForTesting();
   EXPECT_EQ(1, test_wallpaper_controller_.show_always_on_top_wallpaper_count());
   EXPECT_EQ(1,
             test_wallpaper_controller_.remove_always_on_top_wallpaper_count());
@@ -489,14 +484,12 @@
             test_wallpaper_controller_.remove_always_on_top_wallpaper_count());
   session_manager_->SetSessionState(
       session_manager::SessionState::LOGIN_PRIMARY);
-  wallpaper_controller_client_->FlushForTesting();
   EXPECT_EQ(0, test_wallpaper_controller_.show_always_on_top_wallpaper_count());
   EXPECT_EQ(0,
             test_wallpaper_controller_.remove_always_on_top_wallpaper_count());
 
   ASSERT_TRUE(FinishResourcesComponentLoad(
       base::FilePath(kTestDemoModeResourcesMountPoint)));
-  wallpaper_controller_client_->FlushForTesting();
   EXPECT_EQ(1, test_wallpaper_controller_.show_always_on_top_wallpaper_count());
   EXPECT_EQ(0,
             test_wallpaper_controller_.remove_always_on_top_wallpaper_count());
@@ -505,7 +498,6 @@
       static_cast<base::MockOneShotTimer*>(demo_session->GetTimerForTesting());
   ASSERT_TRUE(timer_ptr);
   timer_ptr->Fire();
-  wallpaper_controller_client_->FlushForTesting();
   EXPECT_EQ(1, test_wallpaper_controller_.show_always_on_top_wallpaper_count());
   EXPECT_EQ(1,
             test_wallpaper_controller_.remove_always_on_top_wallpaper_count());
@@ -525,13 +517,11 @@
       profile, new ChromeAppDelegate(true /* keep_alive */),
       screensaver_app.get());
   demo_session->OnAppWindowActivated(app_window);
-  wallpaper_controller_client_->FlushForTesting();
   EXPECT_EQ(1, test_wallpaper_controller_.show_always_on_top_wallpaper_count());
   EXPECT_EQ(1,
             test_wallpaper_controller_.remove_always_on_top_wallpaper_count());
   // Entering active session will not trigger splash screen removal anymore.
   session_manager_->SetSessionState(session_manager::SessionState::ACTIVE);
-  wallpaper_controller_client_->FlushForTesting();
   EXPECT_EQ(1, test_wallpaper_controller_.show_always_on_top_wallpaper_count());
   EXPECT_EQ(1,
             test_wallpaper_controller_.remove_always_on_top_wallpaper_count());
diff --git a/chrome/browser/chromeos/login/kiosk_browsertest.cc b/chrome/browser/chromeos/login/kiosk_browsertest.cc
index 9a1bdbcc..dfdedf6 100644
--- a/chrome/browser/chromeos/login/kiosk_browsertest.cc
+++ b/chrome/browser/chromeos/login/kiosk_browsertest.cc
@@ -8,8 +8,8 @@
 #include "apps/test/app_window_waiter.h"
 #include "ash/public/cpp/ash_switches.h"
 #include "ash/public/cpp/keyboard/keyboard_switches.h"
+#include "ash/public/cpp/wallpaper_controller_observer.h"
 #include "ash/public/interfaces/login_screen_test_api.test-mojom-test-utils.h"
-#include "ash/public/interfaces/wallpaper.mojom.h"
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/json/json_reader.h"
@@ -92,7 +92,6 @@
 #include "google_apis/gaia/gaia_switches.h"
 #include "google_apis/gaia/gaia_urls.h"
 #include "media/audio/test_audio_thread.h"
-#include "mojo/public/cpp/bindings/associated_binding.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "services/audio/public/cpp/fake_system_info.h"
 #include "services/audio/public/cpp/sounds/audio_stream_handler.h"
@@ -2477,20 +2476,19 @@
 // Specialized test fixture for testing kiosk mode on the
 // hidden WebUI initialization flow for slow hardware.
 class KioskHiddenWebUITest : public KioskTest,
-                             public ash::mojom::WallpaperObserver {
+                             public ash::WallpaperControllerObserver {
  public:
-  KioskHiddenWebUITest() : wallpaper_loaded_(false), observer_binding_(this) {}
+  KioskHiddenWebUITest() = default;
 
+  // KioskTest:
   void SetUpOnMainThread() override {
     LoginDisplayHostWebUI::DisableRestrictiveProxyCheckForTest();
 
     KioskTest::SetUpOnMainThread();
-    ash::mojom::WallpaperObserverAssociatedPtrInfo ptr_info;
-    observer_binding_.Bind(mojo::MakeRequest(&ptr_info));
-    WallpaperControllerClient::Get()->AddObserver(std::move(ptr_info));
+    WallpaperControllerClient::Get()->AddObserver(this);
   }
-
   void TearDownOnMainThread() override {
+    WallpaperControllerClient::Get()->RemoveObserver(this);
     KioskTest::TearDownOnMainThread();
   }
 
@@ -2503,24 +2501,16 @@
 
   bool wallpaper_loaded() const { return wallpaper_loaded_; }
 
-  // ash::mojom::WallpaperObserver:
-  void OnWallpaperChanged(uint32_t image_id) override {
+  // ash::WallpaperControllerObserver:
+  void OnWallpaperChanged() override {
     wallpaper_loaded_ = true;
     if (runner_.get())
       runner_->Quit();
   }
 
-  void OnWallpaperColorsChanged(
-      const std::vector<SkColor>& prominent_colors) override {}
-
-  void OnWallpaperBlurChanged(bool blurred) override {}
-
-  bool wallpaper_loaded_;
-  scoped_refptr<content::MessageLoopRunner> runner_;
-
  private:
-  // The binding this instance uses to implement ash::mojom::WallpaperObserver.
-  mojo::AssociatedBinding<ash::mojom::WallpaperObserver> observer_binding_;
+  bool wallpaper_loaded_ = false;
+  scoped_refptr<content::MessageLoopRunner> runner_;
 
   DISALLOW_COPY_AND_ASSIGN(KioskHiddenWebUITest);
 };
diff --git a/chrome/browser/chromeos/login/users/user_manager_unittest.cc b/chrome/browser/chromeos/login/users/user_manager_unittest.cc
index 9f73e62..9830a82 100644
--- a/chrome/browser/chromeos/login/users/user_manager_unittest.cc
+++ b/chrome/browser/chromeos/login/users/user_manager_unittest.cc
@@ -83,8 +83,7 @@
 
     wallpaper_controller_client_ =
         std::make_unique<WallpaperControllerClient>();
-    wallpaper_controller_client_->InitForTesting(
-        test_wallpaper_controller_.CreateInterfacePtr());
+    wallpaper_controller_client_->InitForTesting(&test_wallpaper_controller_);
   }
 
   void TearDown() override {
@@ -218,7 +217,6 @@
   EXPECT_EQ(1U, users->size());
   EXPECT_EQ((*users)[0]->GetAccountId(), owner_account_id_at_invalid_domain_);
   // Verify that the wallpaper is removed when user is removed.
-  wallpaper_controller_client_->FlushForTesting();
   EXPECT_EQ(2, test_wallpaper_controller_.remove_user_wallpaper_count());
 }
 
diff --git a/chrome/browser/chromeos/login/users/wallpaper_policy_browsertest.cc b/chrome/browser/chromeos/login/users/wallpaper_policy_browsertest.cc
index 553f95ec..3f7ad74 100644
--- a/chrome/browser/chromeos/login/users/wallpaper_policy_browsertest.cc
+++ b/chrome/browser/chromeos/login/users/wallpaper_policy_browsertest.cc
@@ -8,7 +8,7 @@
 #include <string>
 #include <vector>
 
-#include "ash/public/interfaces/wallpaper.mojom.h"
+#include "ash/public/cpp/wallpaper_controller_observer.h"
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/compiler_specific.h"
@@ -56,7 +56,6 @@
 #include "components/user_manager/user_names.h"
 #include "content/public/test/browser_test_utils.h"
 #include "crypto/rsa_private_key.h"
-#include "mojo/public/cpp/bindings/associated_binding.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkBitmap.h"
@@ -130,7 +129,7 @@
 }  // namespace
 
 class WallpaperPolicyTest : public LoginManagerTest,
-                            public ash::mojom::WallpaperObserver {
+                            public ash::WallpaperControllerObserver {
  protected:
   WallpaperPolicyTest()
       : LoginManagerTest(true, true),
@@ -204,9 +203,7 @@
 
   void SetUpOnMainThread() override {
     LoginManagerTest::SetUpOnMainThread();
-    ash::mojom::WallpaperObserverAssociatedPtrInfo ptr_info;
-    observer_binding_.Bind(mojo::MakeRequest(&ptr_info));
-    WallpaperControllerClient::Get()->AddObserver(std::move(ptr_info));
+    WallpaperControllerClient::Get()->AddObserver(this);
 
     // Set up policy signing.
     user_policy_builders_[0] = GetUserPolicyBuilder(testUsers_[0]);
@@ -214,45 +211,30 @@
   }
 
   void TearDownOnMainThread() override {
+    WallpaperControllerClient::Get()->RemoveObserver(this);
     LoginManagerTest::TearDownOnMainThread();
   }
 
   // Obtain wallpaper image and return its average ARGB color.
   SkColor GetAverageWallpaperColor() {
     average_color_.reset();
-    WallpaperControllerClient::Get()->GetWallpaperImage(
-        base::BindOnce(&WallpaperPolicyTest::OnGetWallpaperImageCallback,
-                       weak_ptr_factory_.GetWeakPtr()));
-    while (!average_color_.has_value()) {
-      run_loop_.reset(new base::RunLoop);
-      run_loop_->Run();
-    }
-    return average_color_.value();
-  }
-
-  void OnGetWallpaperImageCallback(const gfx::ImageSkia& image) {
+    auto image = WallpaperControllerClient::Get()->GetWallpaperImage();
     const gfx::ImageSkiaRep& representation = image.GetRepresentation(1.0f);
     if (representation.is_null()) {
       ADD_FAILURE() << "No image representation.";
       average_color_ = SkColorSetARGB(0, 0, 0, 0);
     }
     average_color_ = ComputeAverageColor(representation.GetBitmap());
-    if (run_loop_)
-      run_loop_->Quit();
+    return average_color_.value();
   }
 
-  // ash::mojom::WallpaperObserver:
-  void OnWallpaperChanged(uint32_t image_id) override {
+  // ash::WallpaperControllerObserver:
+  void OnWallpaperChanged() override {
     ++wallpaper_change_count_;
     if (run_loop_)
       run_loop_->Quit();
   }
 
-  void OnWallpaperColorsChanged(
-      const std::vector<SkColor>& prominent_colors) override {}
-
-  void OnWallpaperBlurChanged(bool blurred) override {}
-
   // Runs the loop until wallpaper has changed to the expected color.
   void RunUntilWallpaperChangeToColor(const SkColor& expected_color) {
     while (expected_color != GetAverageWallpaperColor()) {
@@ -335,10 +317,6 @@
       &mixin_host_, DeviceStateMixin::State::OOBE_COMPLETED_CLOUD_ENROLLED};
 
  private:
-  // The binding this instance uses to implement ash::mojom::WallpaperObserver.
-  mojo::AssociatedBinding<ash::mojom::WallpaperObserver> observer_binding_{
-      this};
-
   // The average ARGB color of the current wallpaper.
   base::Optional<SkColor> average_color_;
 
diff --git a/chrome/browser/chromeos/note_taking_controller_client.cc b/chrome/browser/chromeos/note_taking_controller_client.cc
index 15b4607..8acb90c 100644
--- a/chrome/browser/chromeos/note_taking_controller_client.cc
+++ b/chrome/browser/chromeos/note_taking_controller_client.cc
@@ -4,21 +4,16 @@
 
 #include "chrome/browser/chromeos/note_taking_controller_client.h"
 
-#include "ash/public/interfaces/constants.mojom.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_source.h"
-#include "content/public/common/service_manager_connection.h"
-#include "mojo/public/cpp/bindings/binding.h"
-#include "services/service_manager/public/cpp/connector.h"
 
 namespace chromeos {
 
 NoteTakingControllerClient::NoteTakingControllerClient(NoteTakingHelper* helper)
-    : helper_(helper), note_observer_(this), binding_(this) {
-  note_observer_.Add(helper_);
+    : helper_(helper) {
   registrar_.Add(this, chrome::NOTIFICATION_SESSION_STARTED,
                  content::NotificationService::AllSources());
   registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
@@ -27,35 +22,14 @@
 
 NoteTakingControllerClient::~NoteTakingControllerClient() = default;
 
+bool NoteTakingControllerClient::CanCreateNote() {
+  return profile_ && helper_->IsAppAvailable(profile_);
+}
+
 void NoteTakingControllerClient::CreateNote() {
   helper_->LaunchAppForNewNote(profile_, base::FilePath());
 }
 
-void NoteTakingControllerClient::OnAvailableNoteTakingAppsUpdated() {
-  bool has_app = profile_ && helper_->IsAppAvailable(profile_);
-
-  // No need to rebind the client if already connected.
-  if (binding_.is_bound() == has_app)
-    return;
-
-  if (binding_.is_bound()) {
-    binding_.Close();
-  } else {
-    // Connector can be overridden for testing.
-    if (!connector_) {
-      connector_ =
-          content::ServiceManagerConnection::GetForProcess()->GetConnector();
-    }
-    connector_->BindInterface(ash::mojom::kServiceName, &controller_);
-    ash::mojom::NoteTakingControllerClientPtr client;
-    binding_.Bind(mojo::MakeRequest(&client));
-    controller_->SetClient(std::move(client));
-  }
-}
-
-void NoteTakingControllerClient::OnPreferredNoteTakingAppUpdated(
-    Profile* profile) {}
-
 void NoteTakingControllerClient::ActiveUserChanged(
     const user_manager::User* active_user) {
   SetProfile(ProfileHelper::Get()->GetProfileByUser(active_user));
@@ -88,7 +62,6 @@
 
 void NoteTakingControllerClient::SetProfile(Profile* profile) {
   profile_ = profile;
-  OnAvailableNoteTakingAppsUpdated();
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/note_taking_controller_client.h b/chrome/browser/chromeos/note_taking_controller_client.h
index fcf309a6..937c6ef 100644
--- a/chrome/browser/chromeos/note_taking_controller_client.h
+++ b/chrome/browser/chromeos/note_taking_controller_client.h
@@ -5,38 +5,29 @@
 #ifndef CHROME_BROWSER_CHROMEOS_NOTE_TAKING_CONTROLLER_CLIENT_H_
 #define CHROME_BROWSER_CHROMEOS_NOTE_TAKING_CONTROLLER_CLIENT_H_
 
-#include "ash/public/interfaces/note_taking_controller.mojom.h"
+#include "ash/public/cpp/note_taking_client.h"
 #include "base/macros.h"
 #include "chrome/browser/chromeos/note_taking_helper.h"
 #include "components/user_manager/user_manager.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
-#include "mojo/public/cpp/bindings/binding.h"
 
 class Profile;
 
-namespace service_manager {
-class Connector;
-}
-
 namespace chromeos {
 
 class NoteTakingControllerClient
-    : public ash::mojom::NoteTakingControllerClient,
-      public NoteTakingHelper::Observer,
+    : public ash::NoteTakingClient,
       public user_manager::UserManager::UserSessionStateObserver,
       public content::NotificationObserver {
  public:
   explicit NoteTakingControllerClient(NoteTakingHelper* helper);
   ~NoteTakingControllerClient() override;
 
-  // ash::mojom::NoteTakingControllerClient:
+  // ash::NoteTakingClient:
+  bool CanCreateNote() override;
   void CreateNote() override;
 
-  // chromeos::NoteTakingHelper::Observer:
-  void OnAvailableNoteTakingAppsUpdated() override;
-  void OnPreferredNoteTakingAppUpdated(Profile* profile) override;
-
   // user_manager::UserManager::UserSessionStateObserver:
   void ActiveUserChanged(const user_manager::User* active_user) override;
 
@@ -45,17 +36,8 @@
                const content::NotificationSource& source,
                const content::NotificationDetails& details) override;
 
-  void SetConnectorForTesting(service_manager::Connector* connector) {
-    connector_ = connector;
-  }
-
   void SetProfileForTesting(Profile* profile) { SetProfile(profile); }
 
-  void FlushMojoForTesting() {
-    if (controller_)
-      controller_.FlushForTesting();
-  }
-
  private:
   void SetProfile(Profile* profile);
 
@@ -65,15 +47,10 @@
   // Unowned pointer to the active profile.
   Profile* profile_ = nullptr;
 
-  ScopedObserver<NoteTakingHelper, NoteTakingHelper::Observer> note_observer_;
   content::NotificationRegistrar registrar_;
   std::unique_ptr<user_manager::ScopedUserSessionStateObserver>
       session_state_observer_;
 
-  mojo::Binding<ash::mojom::NoteTakingControllerClient> binding_;
-  service_manager::Connector* connector_ = nullptr;
-  ash::mojom::NoteTakingControllerPtr controller_;
-
   DISALLOW_COPY_AND_ASSIGN(NoteTakingControllerClient);
 };
 
diff --git a/chrome/browser/chromeos/note_taking_helper_unittest.cc b/chrome/browser/chromeos/note_taking_helper_unittest.cc
index 4ad4fd2..960a44e 100644
--- a/chrome/browser/chromeos/note_taking_helper_unittest.cc
+++ b/chrome/browser/chromeos/note_taking_helper_unittest.cc
@@ -7,7 +7,6 @@
 #include <utility>
 
 #include "ash/public/cpp/ash_switches.h"
-#include "ash/public/interfaces/constants.mojom.h"
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/files/file_path.h"
@@ -47,9 +46,6 @@
 #include "extensions/common/extension_builder.h"
 #include "extensions/common/extension_id.h"
 #include "extensions/common/value_builder.h"
-#include "services/service_manager/public/cpp/service.h"
-#include "services/service_manager/public/cpp/service_binding.h"
-#include "services/service_manager/public/cpp/test/test_connector_factory.h"
 #include "url/gurl.h"
 
 namespace app_runtime = extensions::api::app_runtime;
@@ -148,53 +144,6 @@
   DISALLOW_COPY_AND_ASSIGN(TestObserver);
 };
 
-class TestNoteTakingController : public ash::mojom::NoteTakingController,
-                                 public service_manager::Service {
- public:
-  explicit TestNoteTakingController(
-      service_manager::mojom::ServiceRequest request)
-      : service_binding_(this, std::move(request)) {}
-
-  ~TestNoteTakingController() override = default;
-
-  void CallCreateNote() {
-    client_->CreateNote();
-    client_.FlushForTesting();
-  }
-
-  bool client_attached() const { return static_cast<bool>(client_); }
-
-  // ash::mojom::NoteTakingController:
-  void SetClient(ash::mojom::NoteTakingControllerClientPtr client) override {
-    DCHECK(!client_);
-    client_ = std::move(client);
-    client_.set_connection_error_handler(
-        base::Bind(&TestNoteTakingController::OnClientConnectionLost,
-                   base::Unretained(this)));
-  }
-
-  // service_manager::Service:
-  void OnBindInterface(const service_manager::BindSourceInfo& source_info,
-                       const std::string& interface_name,
-                       mojo::ScopedMessagePipeHandle interface_pipe) override {
-    DCHECK(interface_name == ash::mojom::NoteTakingController::Name_);
-    binding_.Bind(
-        ash::mojom::NoteTakingControllerRequest(std::move(interface_pipe)));
-  }
-
- private:
-  void OnClientConnectionLost() {
-    client_.reset();
-    binding_.Close();
-  }
-
-  service_manager::ServiceBinding service_binding_;
-  mojo::Binding<ash::mojom::NoteTakingController> binding_{this};
-  ash::mojom::NoteTakingControllerClientPtr client_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestNoteTakingController);
-};
-
 }  // namespace
 
 class NoteTakingHelperTest : public BrowserWithTestWindowTest {
@@ -240,10 +189,6 @@
 
   static NoteTakingHelper* helper() { return NoteTakingHelper::Get(); }
 
-  TestNoteTakingController* test_note_taking_controller() {
-    return test_note_taking_controller_.get();
-  }
-
   NoteTakingControllerClient* note_taking_client() {
     return helper()->GetNoteTakingControllerClientForTesting();
   }
@@ -251,12 +196,6 @@
   void SetNoteTakingClientProfile(Profile* profile) {
     if (note_taking_client())
       note_taking_client()->SetProfileForTesting(profile);
-    FlushNoteTakingClientMojo();
-  }
-
-  void FlushNoteTakingClientMojo() {
-    if (note_taking_client())
-      note_taking_client()->FlushMojoForTesting();
   }
 
   // Initializes ARC and NoteTakingHelper. |flags| contains OR-ed together
@@ -291,11 +230,6 @@
     NoteTakingHelper::Get()->SetProfileWithEnabledLockScreenApps(profile());
     NoteTakingHelper::Get()->set_launch_chrome_app_callback_for_test(base::Bind(
         &NoteTakingHelperTest::LaunchChromeApp, base::Unretained(this)));
-
-    test_note_taking_controller_ = std::make_unique<TestNoteTakingController>(
-        connector_factory_.RegisterInstance(ash::mojom::kServiceName));
-    note_taking_client()->SetConnectorForTesting(
-        connector_factory_.GetDefaultConnector());
   }
 
   // Creates an extension.
@@ -355,7 +289,6 @@
     extensions::ExtensionSystem::Get(profile)
         ->extension_service()
         ->AddExtension(extension);
-    FlushNoteTakingClientMojo();
   }
   void UninstallExtension(const extensions::Extension* extension,
                           Profile* profile) {
@@ -365,7 +298,6 @@
         ->UninstallExtension(
             extension->id(),
             extensions::UninstallReason::UNINSTALL_REASON_FOR_TESTING, &error);
-    FlushNoteTakingClientMojo();
   }
 
   scoped_refptr<const extensions::Extension> CreateAndInstallLockScreenApp(
@@ -494,8 +426,6 @@
 
   ArcAppTest arc_test_;
   std::unique_ptr<arc::ArcIntentHelperBridge> intent_helper_bridge_;
-  service_manager::TestConnectorFactory connector_factory_;
-  std::unique_ptr<TestNoteTakingController> test_note_taking_controller_;
 
   DISALLOW_COPY_AND_ASSIGN(NoteTakingHelperTest);
 };
@@ -1501,7 +1431,8 @@
   Init(ENABLE_PALETTE);
 
   auto has_note_taking_apps = [&]() {
-    return test_note_taking_controller()->client_attached();
+    auto* client = ash::NoteTakingClient::GetInstance();
+    return client && client->CanCreateNote();
   };
 
   EXPECT_FALSE(has_note_taking_apps());
@@ -1543,7 +1474,7 @@
   SetNoteTakingClientProfile(profile());
   EXPECT_TRUE(has_note_taking_apps());
 
-  test_note_taking_controller()->CallCreateNote();
+  ash::NoteTakingClient::GetInstance()->CreateNote();
   ASSERT_EQ(1u, launched_chrome_apps_.size());
   ASSERT_EQ(NoteTakingHelper::kProdKeepExtensionId,
             launched_chrome_apps_[0].id);
diff --git a/chrome/browser/extensions/active_tab_unittest.cc b/chrome/browser/extensions/active_tab_unittest.cc
index 62a4b0c..fd6031c 100644
--- a/chrome/browser/extensions/active_tab_unittest.cc
+++ b/chrome/browser/extensions/active_tab_unittest.cc
@@ -544,8 +544,7 @@
         TestingBrowserProcess::GetGlobal());
     wallpaper_controller_client_ =
         std::make_unique<WallpaperControllerClient>();
-    wallpaper_controller_client_->InitForTesting(
-        test_wallpaper_controller_.CreateInterfacePtr());
+    wallpaper_controller_client_->InitForTesting(&test_wallpaper_controller_);
     g_browser_process->local_state()->SetString(
         "PublicAccountPendingDataRemoval", user_email);
     user_manager::UserManager::Get()->UserLoggedIn(account_id, user_id_hash,
diff --git a/chrome/browser/infobars/infobars_browsertest.cc b/chrome/browser/infobars/infobars_browsertest.cc
index e64533c..8cf891b 100644
--- a/chrome/browser/infobars/infobars_browsertest.cc
+++ b/chrome/browser/infobars/infobars_browsertest.cc
@@ -402,7 +402,7 @@
       break;
 
     case IBD::FLASH_DEPRECATION_INFOBAR_DELEGATE:
-      FlashDeprecationInfoBarDelegate::Create(GetInfoBarService());
+      FlashDeprecationInfoBarDelegate::Create(GetInfoBarService(), nullptr);
       break;
     case IBD::TAB_SHARING_INFOBAR_DELEGATE:
       TabSharingInfoBarDelegate::Create(GetInfoBarService(),
diff --git a/chrome/browser/password_manager/auto_signin_first_run_dialog_android.cc b/chrome/browser/password_manager/auto_signin_first_run_dialog_android.cc
index cbae41c..70d7f44 100644
--- a/chrome/browser/password_manager/auto_signin_first_run_dialog_android.cc
+++ b/chrome/browser/password_manager/auto_signin_first_run_dialog_android.cc
@@ -15,6 +15,7 @@
 #include "components/password_manager/core/browser/password_bubble_experiment.h"
 #include "components/password_manager/core/browser/password_manager_constants.h"
 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
+#include "components/strings/grit/components_strings.h"
 #include "jni/AutoSigninFirstRunDialog_jni.h"
 #include "ui/android/window_android.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -56,8 +57,7 @@
           : IDS_AUTO_SIGNIN_FIRST_RUN_TITLE_LOCAL_DEVICE);
   base::string16 ok_button_text =
       l10n_util::GetStringUTF16(IDS_AUTO_SIGNIN_FIRST_RUN_OK);
-  base::string16 turn_off_button_text =
-      l10n_util::GetStringUTF16(IDS_AUTO_SIGNIN_FIRST_RUN_TURN_OFF);
+  base::string16 turn_off_button_text = l10n_util::GetStringUTF16(IDS_TURN_OFF);
 
   dialog_jobject_.Reset(Java_AutoSigninFirstRunDialog_createAndShowDialog(
       env, native_window->GetJavaObject(), reinterpret_cast<intptr_t>(this),
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc
index 64118c9..a03ff88e 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -679,11 +679,14 @@
 
 #if defined(SYNC_PASSWORD_REUSE_DETECTION_ENABLED)
 void ChromePasswordManagerClient::OnPaste() {
-  ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
+  password_reuse_detection_manager_.OnPaste(GetTextFromClipboard());
+}
+
+base::string16 ChromePasswordManagerClient::GetTextFromClipboard() {
   base::string16 text;
-  clipboard->ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE, &text);
-  was_on_paste_called_ = true;
-  password_reuse_detection_manager_.OnPaste(std::move(text));
+  ui::Clipboard::GetForCurrentThread()->ReadText(ui::CLIPBOARD_TYPE_COPY_PASTE,
+                                                 &text);
+  return text;
 }
 #endif
 
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.h b/chrome/browser/password_manager/chrome_password_manager_client.h
index a2eaf7d..adca9ab6 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.h
+++ b/chrome/browser/password_manager/chrome_password_manager_client.h
@@ -185,7 +185,6 @@
   bool has_binding_for_credential_manager() const {
     return content_credential_manager_.HasBinding();
   }
-  bool was_on_paste_called() const { return was_on_paste_called_; }
 #endif
 
  protected:
@@ -193,6 +192,12 @@
   ChromePasswordManagerClient(content::WebContents* web_contents,
                               autofill::AutofillClient* autofill_client);
 
+  // content::WebContentsObserver override
+#if defined(SYNC_PASSWORD_REUSE_DETECTION_ENABLED)
+  void OnPaste() override;
+  base::string16 GetTextFromClipboard();
+#endif
+
  private:
   friend class content::WebContentsUserData<ChromePasswordManagerClient>;
 
@@ -201,9 +206,6 @@
       content::NavigationHandle* navigation_handle) override;
   void DidFinishNavigation(
       content::NavigationHandle* navigation_handle) override;
-#if defined(SYNC_PASSWORD_REUSE_DETECTION_ENABLED)
-  void OnPaste() override;
-#endif
 
 // TODO(crbug.com/706392): Fix password reuse detection for Android.
 #if !defined(OS_ANDROID)
@@ -289,9 +291,6 @@
   // WebContents. Used for testing.
   bool was_store_ever_called_ = false;
 
-  // Whether OnPaste() was called from this ChromePasswordManagerClient
-  bool was_on_paste_called_ = false;
-
   // Helper for performing logic that is common between
   // ChromePasswordManagerClient and IOSChromePasswordManagerClient.
   password_manager::PasswordManagerClientHelper helper_;
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc
index 00ffe8c..b30346b3 100644
--- a/chrome/browser/password_manager/password_manager_browsertest.cc
+++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -47,6 +47,7 @@
 #include "components/password_manager/content/browser/content_password_manager_driver_factory.h"
 #include "components/password_manager/core/browser/http_auth_manager.h"
 #include "components/password_manager/core/browser/http_auth_observer.h"
+#include "components/password_manager/core/browser/mock_password_store.h"
 #include "components/password_manager/core/browser/new_password_form_manager.h"
 #include "components/password_manager/core/browser/test_password_store.h"
 #include "components/password_manager/core/common/password_manager_features.h"
@@ -63,12 +64,14 @@
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test_utils.h"
+#include "content/public/test/web_contents_tester.h"
 #include "net/base/filename_util.h"
 #include "net/test/embedded_test_server/http_request.h"
 #include "net/test/embedded_test_server/http_response.h"
 #include "net/url_request/test_url_fetcher_factory.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "third_party/blink/public/platform/web_input_event.h"
+#include "ui/base/clipboard/test/test_clipboard.h"
 #include "ui/base/ui_base_switches.h"
 #include "ui/events/keycodes/keyboard_codes.h"
 #include "ui/gfx/geometry/point.h"
@@ -4061,5 +4064,22 @@
   WaitForElementValue("password_field", "pw");
 }
 
+IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTest,
+                       CheckOnPasteCalledForPasteEvent) {
+  ::ui::Clipboard::SetClipboardForCurrentThread(
+      std::make_unique<::ui::TestClipboard>());
+  const std::string password = "password";
+  static_cast<::ui::TestClipboard*>(::ui::Clipboard::GetForCurrentThread())
+      ->WriteText(password.data(), password.length());
+  NavigateToFile("/password/password_form.html");
+  CustomPasswordManagerClient* client =
+      static_cast<CustomPasswordManagerClient*>(
+          ChromePasswordManagerClient::FromWebContents(WebContents()));
+  content::SimulateKeyPress(WebContents(), ::ui::DomKey::PASTE,
+                            ::ui::DomCode::PASTE, ::ui::VKEY_PASTE, true, true,
+                            false, true);
+  EXPECT_EQ(client->pasted_value(), base::ASCIIToUTF16("password"));
+}
+
 }  // namespace
 }  // namespace password_manager
diff --git a/chrome/browser/password_manager/password_manager_test_base.cc b/chrome/browser/password_manager/password_manager_test_base.cc
index a4c7906d..f0a46cd 100644
--- a/chrome/browser/password_manager/password_manager_test_base.cc
+++ b/chrome/browser/password_manager/password_manager_test_base.cc
@@ -63,26 +63,6 @@
   DISALLOW_COPY_AND_ASSIGN(PasswordStoreResultsObserver);
 };
 
-// Custom class is required to enable password generation.
-class CustomPasswordManagerClient : public ChromePasswordManagerClient {
- public:
-  using ChromePasswordManagerClient::ChromePasswordManagerClient;
-
-  static void CreateForWebContentsWithAutofillClient(
-      content::WebContents* contents,
-      autofill::AutofillClient* autofill_client) {
-    ASSERT_FALSE(FromWebContents(contents));
-    contents->SetUserData(UserDataKey(),
-                          base::WrapUnique(new CustomPasswordManagerClient(
-                              contents, autofill_client)));
-  }
-
-  // PasswordManagerClient:
-  password_manager::SyncState GetPasswordSyncState() const override {
-    return password_manager::SYNCING_NORMAL_ENCRYPTION;
-  }
-};
-
 // ManagePasswordsUIController subclass to capture the UI events.
 class CustomManagePasswordsUIController : public ManagePasswordsUIController {
  public:
@@ -304,6 +284,25 @@
 };
 
 }  // namespace
+void CustomPasswordManagerClient::CreateForWebContentsWithAutofillClient(
+    content::WebContents* contents,
+    autofill::AutofillClient* autofill_client) {
+  ASSERT_FALSE(FromWebContents(contents));
+  contents->SetUserData(UserDataKey(),
+                        base::WrapUnique(new CustomPasswordManagerClient(
+                            contents, autofill_client)));
+}
+
+// PasswordManagerClient:
+password_manager::SyncState CustomPasswordManagerClient::GetPasswordSyncState()
+    const {
+  return password_manager::SYNCING_NORMAL_ENCRYPTION;
+}
+
+void CustomPasswordManagerClient::OnPaste() {
+  pasted_value_ = ChromePasswordManagerClient::GetTextFromClipboard();
+  ChromePasswordManagerClient::OnPaste();
+}
 
 NavigationObserver::NavigationObserver(content::WebContents* web_contents)
     : content::WebContentsObserver(web_contents),
diff --git a/chrome/browser/password_manager/password_manager_test_base.h b/chrome/browser/password_manager/password_manager_test_base.h
index d99f96c..d222738 100644
--- a/chrome/browser/password_manager/password_manager_test_base.h
+++ b/chrome/browser/password_manager/password_manager_test_base.h
@@ -9,6 +9,7 @@
 
 #include "base/macros.h"
 #include "base/run_loop.h"
+#include "chrome/browser/password_manager/chrome_password_manager_client.h"
 #include "chrome/browser/ssl/cert_verifier_browser_test.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "components/password_manager/core/browser/password_store_consumer.h"
@@ -21,6 +22,26 @@
 
 class ManagePasswordsUIController;
 
+// Custom class is required to enable password generation.
+class CustomPasswordManagerClient : public ChromePasswordManagerClient {
+ public:
+  using ChromePasswordManagerClient::ChromePasswordManagerClient;
+  static void CreateForWebContentsWithAutofillClient(
+      content::WebContents* contents,
+      autofill::AutofillClient* autofill_client);
+
+  // PasswordManagerClient:
+  password_manager::SyncState GetPasswordSyncState() const override;
+
+  void OnPaste() override;
+
+  base::string16 pasted_value() { return pasted_value_; }
+
+ private:
+  // Represents the text passed to PasswordResuseManager's OnPaste() method.
+  base::string16 pasted_value_;
+};
+
 class NavigationObserver : public content::WebContentsObserver {
  public:
   explicit NavigationObserver(content::WebContents* web_contents);
diff --git a/chrome/browser/password_manager/password_store_x.cc b/chrome/browser/password_manager/password_store_x.cc
index e2028ad..394977ce 100644
--- a/chrome/browser/password_manager/password_store_x.cc
+++ b/chrome/browser/password_manager/password_store_x.cc
@@ -182,7 +182,7 @@
   if (use_native_backend() && AddLoginToBackend(backend_, form, &changes)) {
     allow_fallback_ = false;
   } else if (allow_default_store()) {
-    changes = PasswordStoreDefault::AddLoginImpl(form);
+    changes = PasswordStoreDefault::AddLoginImpl(form, error);
   }
   return changes;
 }
diff --git a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
index 841aa7b..2616a33 100644
--- a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
+++ b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
@@ -93,6 +93,9 @@
   DISALLOW_COPY_AND_ASSIGN(MockPictureInPictureWindowController);
 };
 
+const base::FilePath::CharType kPictureInPictureWindowSizePage[] =
+    FILE_PATH_LITERAL("media/picture-in-picture/window-size.html");
+
 }  // namespace
 
 class PictureInPictureWindowControllerBrowserTest
@@ -120,11 +123,10 @@
     return mock_controller_;
   }
 
-  void LoadTabAndEnterPictureInPicture(Browser* browser) {
+  void LoadTabAndEnterPictureInPicture(Browser* browser,
+                                       const base::FilePath& file_path) {
     GURL test_page_url = ui_test_utils::GetTestUrl(
-        base::FilePath(base::FilePath::kCurrentDirectory),
-        base::FilePath(
-            FILE_PATH_LITERAL("media/picture-in-picture/window-size.html")));
+        base::FilePath(base::FilePath::kCurrentDirectory), file_path);
     ui_test_utils::NavigateToURL(browser, test_page_url);
 
     content::WebContents* active_web_contents =
@@ -203,8 +205,7 @@
                        CreationAndVisibilityAndActivation) {
   GURL test_page_url = ui_test_utils::GetTestUrl(
       base::FilePath(base::FilePath::kCurrentDirectory),
-      base::FilePath(
-          FILE_PATH_LITERAL("media/picture-in-picture/window-size.html")));
+      base::FilePath(kPictureInPictureWindowSizePage));
   ui_test_utils::NavigateToURL(browser(), test_page_url);
 
   content::WebContents* active_web_contents =
@@ -267,12 +268,12 @@
     quit_run_loop.Run();
   }
 
-  bool SaveBitmap(base::FilePath& file_path, SkBitmap& bitmap) {
-    std::vector<unsigned char> png_data;
-    CHECK(gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &png_data));
-    char* data = reinterpret_cast<char*>(&png_data[0]);
-    int size = static_cast<int>(png_data.size());
-    return base::WriteFile(file_path, data, size) == size;
+  bool ReadImageFile(const base::FilePath& file_path, SkBitmap* read_image) {
+    std::string png_string;
+    base::ReadFileToString(file_path, &png_string);
+    return gfx::PNGCodec::Decode(
+        reinterpret_cast<const unsigned char*>(png_string.data()),
+        png_string.length(), read_image);
   }
 
   void TakeOverlayWindowScreenshot(OverlayWindowViews* overlay_window_views) {
@@ -288,12 +289,10 @@
     run_loop.Run();
   }
 
-  bool CompareImages(const SkBitmap& actual_bmp) {
+  bool CompareImages(const SkBitmap& actual_bmp, const SkBitmap& expected_bmp) {
     // Allowable error and thresholds because of small color shift by
     // video to image conversion and GPU issues.
-    const int allowable_error = 2;
-    const unsigned high_threshold = 0xff - allowable_error;
-    const unsigned low_threshold = 0x00 + allowable_error;
+    const int kAllowableError = 3;
     // Number of pixels with an error
     int error_pixels_count = 0;
     gfx::Rect error_bounding_rect;
@@ -301,12 +300,13 @@
     for (int x = 0; x < actual_bmp.width(); ++x) {
       for (int y = 0; y < actual_bmp.height(); ++y) {
         SkColor actual_color = actual_bmp.getColor(x, y);
-        // Check color is Yellow and is within the tolerance range.
-        // TODO(cliffordcheng): Compare with an expected image instead of just
-        // checking pixel RGB color.
-        if (SkColorGetR(actual_color) < high_threshold &&
-            SkColorGetG(actual_color) < high_threshold &&
-            SkColorGetB(actual_color) > low_threshold) {
+        SkColor expected_color = expected_bmp.getColor(x, y);
+        if ((fabs(SkColorGetR(actual_color) - SkColorGetR(expected_color)) >
+             kAllowableError) ||
+            (fabs(SkColorGetG(actual_color) - SkColorGetG(expected_color)) >
+             kAllowableError) ||
+            (fabs(SkColorGetB(actual_color) - SkColorGetB(expected_color))) >
+                kAllowableError) {
           ++error_pixels_count;
           error_bounding_rect.Union(gfx::Rect(x, y, 1, 1));
         }
@@ -338,38 +338,26 @@
 // Picture-in-Picture window and verifies it's as expected.
 IN_PROC_BROWSER_TEST_F(PictureInPicturePixelComparisonBrowserTest, VideoPlay) {
   base::ScopedAllowBlockingForTesting allow_blocking;
-  GURL test_page_url = ui_test_utils::GetTestUrl(
-      base::FilePath(base::FilePath::kCurrentDirectory),
-      base::FilePath(
-          FILE_PATH_LITERAL("media/picture-in-picture/pixel_test.html")));
-  ui_test_utils::NavigateToURL(browser(), test_page_url);
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(FILE_PATH_LITERAL(
+                     "media/picture-in-picture/pixel_test.html")));
 
   content::WebContents* active_web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
-  ASSERT_NE(nullptr, active_web_contents);
-
-  EXPECT_TRUE(content::ExecuteScript(active_web_contents, "video.play();"));
-  SetUpWindowController(active_web_contents);
-  ASSERT_NE(nullptr, window_controller());
-
-  ASSERT_NE(nullptr, window_controller()->GetWindowForTesting());
-  ASSERT_FALSE(window_controller()->GetWindowForTesting()->IsVisible());
-
-  bool result = false;
-  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
-      active_web_contents, "enterPictureInPicture();", &result));
-  EXPECT_TRUE(result);
 
   bool in_picture_in_picture = false;
   ASSERT_TRUE(ExecuteScriptAndExtractBool(
       active_web_contents, "isInPictureInPicture();", &in_picture_in_picture));
   EXPECT_TRUE(in_picture_in_picture);
 
+  EXPECT_TRUE(content::ExecuteScript(active_web_contents, "video.play();"));
+  SetUpWindowController(active_web_contents);
+  ASSERT_NE(nullptr, window_controller());
   EXPECT_TRUE(window_controller()->GetWindowForTesting()->IsVisible());
 
   OverlayWindowViews* overlay_window_views = static_cast<OverlayWindowViews*>(
       window_controller()->GetWindowForTesting());
-  overlay_window_views->SetSize(gfx::Size(600, 400));
+  overlay_window_views->SetSize(gfx::Size(402, 268));
   base::string16 expected_title = base::ASCIIToUTF16("resized");
   EXPECT_EQ(expected_title,
             content::TitleWatcher(active_web_contents, expected_title)
@@ -377,11 +365,78 @@
   Wait(base::TimeDelta::FromSeconds(3));
   TakeOverlayWindowScreenshot(overlay_window_views);
 
-  const base::FilePath::StringPieceType test_image =
-      FILE_PATH_LITERAL("pixel_test_actual_0.png");
-  base::FilePath test_image_path = GetFilePath(test_image);
-  ASSERT_TRUE(SaveBitmap(test_image_path, GetResultBitmap()));
-  EXPECT_TRUE(CompareImages(GetResultBitmap()));
+  SkBitmap expected_image;
+  base::FilePath expected_image_path =
+      GetFilePath(FILE_PATH_LITERAL("pixel_expected_video_play.png"));
+  ASSERT_TRUE(ReadImageFile(expected_image_path, &expected_image));
+  EXPECT_TRUE(CompareImages(GetResultBitmap(), expected_image));
+}
+
+// Plays a video in PiP. Trigger the play and pause control in PiP by using a
+// mouse move. Capture the images and verift they are expected.
+IN_PROC_BROWSER_TEST_F(PictureInPicturePixelComparisonBrowserTest,
+                       PlayAndPauseControls) {
+  base::ScopedAllowBlockingForTesting allow_blocking;
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(FILE_PATH_LITERAL(
+                     "media/picture-in-picture/pixel_test.html")));
+  content::WebContents* active_web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+
+  bool in_picture_in_picture = false;
+  ASSERT_TRUE(ExecuteScriptAndExtractBool(
+      active_web_contents, "isInPictureInPicture();", &in_picture_in_picture));
+  EXPECT_TRUE(in_picture_in_picture);
+  EXPECT_TRUE(window_controller()->GetWindowForTesting()->IsVisible());
+
+  OverlayWindowViews* overlay_window_views = static_cast<OverlayWindowViews*>(
+      window_controller()->GetWindowForTesting());
+
+  bool result = false;
+  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
+      active_web_contents, "changeVideoSrc();", &result));
+
+  const int resize_width = 402, resize_height = 268;
+  overlay_window_views->SetSize(gfx::Size(resize_width, resize_height));
+  base::string16 expected_title = base::ASCIIToUTF16("resized");
+  EXPECT_EQ(expected_title,
+            content::TitleWatcher(active_web_contents, expected_title)
+                .WaitAndGetTitle());
+
+  EXPECT_TRUE(content::ExecuteScript(active_web_contents, "video.play();"));
+  Wait(base::TimeDelta::FromSeconds(3));
+  MoveMouseOver(overlay_window_views);
+  TakeOverlayWindowScreenshot(overlay_window_views);
+
+  base::FilePath expected_pause_image_path =
+      GetFilePath(FILE_PATH_LITERAL("pixel_expected_pause_control.png"));
+  base::FilePath expected_play_image_path =
+      GetFilePath(FILE_PATH_LITERAL("pixel_expected_play_control.png"));
+  // If the test image is cropped, usually off by 1 pixel, use another image.
+  if (GetResultBitmap().width() < resize_width ||
+      GetResultBitmap().height() < resize_height) {
+    LOG(INFO) << "Actual image is cropped and backup images are used. "
+              << "Test image dimension: "
+              << "(" << GetResultBitmap().width() << "x"
+              << GetResultBitmap().height() << "). "
+              << "Expected image dimension: "
+              << "(" << resize_width << "x" << resize_height << ")";
+    expected_pause_image_path =
+        GetFilePath(FILE_PATH_LITERAL("pixel_expected_pause_control_crop.png"));
+    expected_play_image_path =
+        GetFilePath(FILE_PATH_LITERAL("pixel_expected_play_control_crop.png"));
+  }
+
+  SkBitmap expected_image;
+  ASSERT_TRUE(ReadImageFile(expected_pause_image_path, &expected_image));
+  EXPECT_TRUE(CompareImages(GetResultBitmap(), expected_image));
+
+  EXPECT_TRUE(content::ExecuteScript(active_web_contents, "video.pause();"));
+  Wait(base::TimeDelta::FromSeconds(3));
+  MoveMouseOver(overlay_window_views);
+  TakeOverlayWindowScreenshot(overlay_window_views);
+  ASSERT_TRUE(ReadImageFile(expected_play_image_path, &expected_image));
+  EXPECT_TRUE(CompareImages(GetResultBitmap(), expected_image));
 }
 #endif  // !defined(OS_CHROMEOS)
 
@@ -391,8 +446,7 @@
                        TabIconUpdated) {
   GURL test_page_url = ui_test_utils::GetTestUrl(
       base::FilePath(base::FilePath::kCurrentDirectory),
-      base::FilePath(
-          FILE_PATH_LITERAL("media/picture-in-picture/window-size.html")));
+      base::FilePath(kPictureInPictureWindowSizePage));
   ui_test_utils::NavigateToURL(browser(), test_page_url);
 
   content::WebContents* active_web_contents =
@@ -428,8 +482,7 @@
                        ResizeEventFired) {
   GURL test_page_url = ui_test_utils::GetTestUrl(
       base::FilePath(base::FilePath::kCurrentDirectory),
-      base::FilePath(
-          FILE_PATH_LITERAL("media/picture-in-picture/window-size.html")));
+      base::FilePath(kPictureInPictureWindowSizePage));
   ui_test_utils::NavigateToURL(browser(), test_page_url);
 
   content::WebContents* active_web_contents =
@@ -464,8 +517,7 @@
                        CloseWindowWhilePlaying) {
   GURL test_page_url = ui_test_utils::GetTestUrl(
       base::FilePath(base::FilePath::kCurrentDirectory),
-      base::FilePath(
-          FILE_PATH_LITERAL("media/picture-in-picture/window-size.html")));
+      base::FilePath(kPictureInPictureWindowSizePage));
   ui_test_utils::NavigateToURL(browser(), test_page_url);
 
   content::WebContents* active_web_contents =
@@ -505,8 +557,7 @@
                        CloseWindowWithoutPlaying) {
   GURL test_page_url = ui_test_utils::GetTestUrl(
       base::FilePath(base::FilePath::kCurrentDirectory),
-      base::FilePath(
-          FILE_PATH_LITERAL("media/picture-in-picture/window-size.html")));
+      base::FilePath(kPictureInPictureWindowSizePage));
   ui_test_utils::NavigateToURL(browser(), test_page_url);
 
   content::WebContents* active_web_contents =
@@ -540,8 +591,7 @@
                        CloseWindowCantEnterPictureInPictureAgain) {
   GURL test_page_url = ui_test_utils::GetTestUrl(
       base::FilePath(base::FilePath::kCurrentDirectory),
-      base::FilePath(
-          FILE_PATH_LITERAL("media/picture-in-picture/window-size.html")));
+      base::FilePath(kPictureInPictureWindowSizePage));
   ui_test_utils::NavigateToURL(browser(), test_page_url);
 
   content::WebContents* active_web_contents =
@@ -579,8 +629,7 @@
                        CloseWindowFromWebAPIWhilePlaying) {
   GURL test_page_url = ui_test_utils::GetTestUrl(
       base::FilePath(base::FilePath::kCurrentDirectory),
-      base::FilePath(
-          FILE_PATH_LITERAL("media/picture-in-picture/window-size.html")));
+      base::FilePath(kPictureInPictureWindowSizePage));
   ui_test_utils::NavigateToURL(browser(), test_page_url);
 
   content::WebContents* active_web_contents =
@@ -618,8 +667,7 @@
                        RequestPictureInPictureTwiceFromSameVideo) {
   GURL test_page_url = ui_test_utils::GetTestUrl(
       base::FilePath(base::FilePath::kCurrentDirectory),
-      base::FilePath(
-          FILE_PATH_LITERAL("media/picture-in-picture/window-size.html")));
+      base::FilePath(kPictureInPictureWindowSizePage));
   ui_test_utils::NavigateToURL(browser(), test_page_url);
 
   content::WebContents* active_web_contents =
@@ -676,8 +724,7 @@
                        OpenSecondPictureInPictureStopsFirst) {
   GURL test_page_url = ui_test_utils::GetTestUrl(
       base::FilePath(base::FilePath::kCurrentDirectory),
-      base::FilePath(
-          FILE_PATH_LITERAL("media/picture-in-picture/window-size.html")));
+      base::FilePath(kPictureInPictureWindowSizePage));
   ui_test_utils::NavigateToURL(browser(), test_page_url);
 
   content::WebContents* active_web_contents =
@@ -722,7 +769,8 @@
 // keep Picture-in-Picture window opened.
 IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest,
                        ResetVideoSrcKeepsPictureInPictureWindowOpened) {
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
 
   EXPECT_TRUE(window_controller()->GetWindowForTesting()->IsVisible());
 
@@ -748,7 +796,8 @@
 // keep Picture-in-Picture window opened.
 IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest,
                        UpdateVideoSrcKeepsPictureInPictureWindowOpened) {
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
 
   EXPECT_TRUE(window_controller()->GetWindowForTesting()->IsVisible());
 
@@ -787,7 +836,8 @@
 IN_PROC_BROWSER_TEST_F(
     PictureInPictureWindowControllerBrowserTest,
     ChangeVideoSrcToMediaStreamKeepsPictureInPictureWindowOpened) {
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
 
   EXPECT_TRUE(window_controller()->GetWindowForTesting()->IsVisible());
 
@@ -850,8 +900,7 @@
                        CloseTwiceSideEffects) {
   GURL test_page_url = ui_test_utils::GetTestUrl(
       base::FilePath(base::FilePath::kCurrentDirectory),
-      base::FilePath(
-          FILE_PATH_LITERAL("media/picture-in-picture/window-size.html")));
+      base::FilePath(kPictureInPictureWindowSizePage));
   ui_test_utils::NavigateToURL(browser(), test_page_url);
 
   content::WebContents* active_web_contents =
@@ -901,8 +950,7 @@
                        PictureInPictureAfterClosingTab) {
   GURL test_page_url = ui_test_utils::GetTestUrl(
       base::FilePath(base::FilePath::kCurrentDirectory),
-      base::FilePath(
-          FILE_PATH_LITERAL("media/picture-in-picture/window-size.html")));
+      base::FilePath(kPictureInPictureWindowSizePage));
   ui_test_utils::NavigateToURL(browser(), test_page_url);
 
   content::WebContents* active_web_contents =
@@ -953,8 +1001,7 @@
                        PictureInPictureDoNotCloseAfterClosingTab) {
   GURL test_page_url = ui_test_utils::GetTestUrl(
       base::FilePath(base::FilePath::kCurrentDirectory),
-      base::FilePath(
-          FILE_PATH_LITERAL("media/picture-in-picture/window-size.html")));
+      base::FilePath(kPictureInPictureWindowSizePage));
   ui_test_utils::NavigateToURL(browser(), test_page_url);
 
   content::WebContents* initial_web_contents =
@@ -1093,8 +1140,7 @@
                        RequestPictureInPictureAfterDisablePictureInPicture) {
   GURL test_page_url = ui_test_utils::GetTestUrl(
       base::FilePath(base::FilePath::kCurrentDirectory),
-      base::FilePath(
-          FILE_PATH_LITERAL("media/picture-in-picture/window-size.html")));
+      base::FilePath(kPictureInPictureWindowSizePage));
   ui_test_utils::NavigateToURL(browser(), test_page_url);
 
   content::WebContents* active_web_contents =
@@ -1200,14 +1246,16 @@
 
 IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest,
                        MultipleBrowserWindowOnePIPWindow) {
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
 
   content::PictureInPictureWindowController* first_controller =
       window_controller();
   EXPECT_TRUE(first_controller->GetWindowForTesting()->IsVisible());
 
   Browser* second_browser = CreateBrowser(browser()->profile());
-  LoadTabAndEnterPictureInPicture(second_browser);
+  LoadTabAndEnterPictureInPicture(
+      second_browser, base::FilePath(kPictureInPictureWindowSizePage));
 
   content::PictureInPictureWindowController* second_controller =
       window_controller();
@@ -1217,7 +1265,8 @@
 
 IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest,
                        EnterPictureInPictureThenFullscreen) {
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
 
   content::WebContents* active_web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
@@ -1236,8 +1285,7 @@
                        EnterFullscreenThenPictureInPicture) {
   GURL test_page_url = ui_test_utils::GetTestUrl(
       base::FilePath(base::FilePath::kCurrentDirectory),
-      base::FilePath(
-          FILE_PATH_LITERAL("media/picture-in-picture/window-size.html")));
+      base::FilePath(kPictureInPictureWindowSizePage));
   ui_test_utils::NavigateToURL(browser(), test_page_url);
 
   content::WebContents* active_web_contents =
@@ -1266,8 +1314,7 @@
                        EnterPictureInPictureThenNavigateAwayCloseWindow) {
   GURL test_page_url = ui_test_utils::GetTestUrl(
       base::FilePath(base::FilePath::kCurrentDirectory),
-      base::FilePath(
-          FILE_PATH_LITERAL("media/picture-in-picture/window-size.html")));
+      base::FilePath(kPictureInPictureWindowSizePage));
   ui_test_utils::NavigateToURL(browser(), test_page_url);
 
   content::WebContents* active_web_contents =
@@ -1302,7 +1349,8 @@
 // doesn't move back to its default position.
 IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest,
                        SurfaceIdChangeDoesNotMoveWindow) {
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
 
   content::WebContents* active_web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
@@ -1352,7 +1400,8 @@
 // is closed at a system level.
 IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest,
                        CloseWindowNotifiesController) {
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
 
   content::WebContents* active_web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
@@ -1372,7 +1421,8 @@
 // Picture-in-Picture is created after a reload.
 IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest,
                        PlayPauseStateAtCreation) {
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
 
   content::WebContents* active_web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
@@ -1435,7 +1485,8 @@
 IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest,
                        EnterUsingWebContentsThenUsingController) {
   // Enter using WebContents.
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
 
   OverlayWindowViews* overlay_window = static_cast<OverlayWindowViews*>(
       window_controller()->GetWindowForTesting());
@@ -1468,7 +1519,8 @@
   // Now show the WebContents based Picture-in-Picture window controller.
   // This should close the existing window and show the new one.
   EXPECT_CALL(mock_controller(), Close(_));
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
 
   OverlayWindowViews* overlay_window = static_cast<OverlayWindowViews*>(
       window_controller()->GetWindowForTesting());
@@ -1585,8 +1637,7 @@
                        HandleMediaKeyPlayPause) {
   GURL test_page_url = ui_test_utils::GetTestUrl(
       base::FilePath(base::FilePath::kCurrentDirectory),
-      base::FilePath(
-          FILE_PATH_LITERAL("media/picture-in-picture/window-size.html")));
+      base::FilePath(kPictureInPictureWindowSizePage));
   ui_test_utils::NavigateToURL(browser(), test_page_url);
 
   content::WebContents* first_active_web_contents =
@@ -1631,8 +1682,7 @@
                        MovingQuadrantsMovesBackToTabAndResizeControls) {
   GURL test_page_url = ui_test_utils::GetTestUrl(
       base::FilePath(base::FilePath::kCurrentDirectory),
-      base::FilePath(
-          FILE_PATH_LITERAL("media/picture-in-picture/window-size.html")));
+      base::FilePath(kPictureInPictureWindowSizePage));
   ui_test_utils::NavigateToURL(browser(), test_page_url);
 
   content::WebContents* active_web_contents =
@@ -1737,7 +1787,8 @@
 // Picture-in-Picture window.
 IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest,
                        PlayPauseButtonVisibility) {
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
 
   content::WebContents* active_web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
@@ -1776,8 +1827,7 @@
                        PageVisibilityEventsFired) {
   GURL test_page_url = ui_test_utils::GetTestUrl(
       base::FilePath(base::FilePath::kCurrentDirectory),
-      base::FilePath(
-          FILE_PATH_LITERAL("media/picture-in-picture/window-size.html")));
+      base::FilePath(kPictureInPictureWindowSizePage));
   ui_test_utils::NavigateToURL(browser(), test_page_url);
 
   content::WebContents* active_web_contents =
@@ -1813,7 +1863,8 @@
 // Picture-in-Picture and video playback is not disrupted.
 IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest,
                        PageVisibilityEventsFiredWhenPictureInPicture) {
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
 
   content::WebContents* active_web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
@@ -1896,7 +1947,8 @@
 // when Media Session Action "skipad" is handled by the website.
 IN_PROC_BROWSER_TEST_F(MediaSessionPictureInPictureWindowControllerBrowserTest,
                        SkipAdButtonVisibility) {
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
   OverlayWindowViews* overlay_window = static_cast<OverlayWindowViews*>(
       window_controller()->GetWindowForTesting());
   ASSERT_TRUE(overlay_window);
@@ -1942,7 +1994,8 @@
 // website even if video is a media stream.
 IN_PROC_BROWSER_TEST_F(MediaSessionPictureInPictureWindowControllerBrowserTest,
                        PlayPauseButtonVisibility) {
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
 
   OverlayWindowViews* overlay_window = static_cast<OverlayWindowViews*>(
       window_controller()->GetWindowForTesting());
@@ -2015,7 +2068,8 @@
 // when Media Session Action "nexttrack" is handled by the website.
 IN_PROC_BROWSER_TEST_F(MediaSessionPictureInPictureWindowControllerBrowserTest,
                        NextTrackButtonVisibility) {
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
   OverlayWindowViews* overlay_window = static_cast<OverlayWindowViews*>(
       window_controller()->GetWindowForTesting());
   ASSERT_TRUE(overlay_window);
@@ -2069,7 +2123,8 @@
 // Picture-in-Picture window controls are hidden.
 IN_PROC_BROWSER_TEST_F(MediaSessionPictureInPictureWindowControllerBrowserTest,
                        NextTrackButtonBounds) {
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
   OverlayWindowViews* overlay_window = static_cast<OverlayWindowViews*>(
       window_controller()->GetWindowForTesting());
   ASSERT_TRUE(overlay_window);
@@ -2095,7 +2150,8 @@
 // window when Media Session Action "previoustrack" is handled by the website.
 IN_PROC_BROWSER_TEST_F(MediaSessionPictureInPictureWindowControllerBrowserTest,
                        PreviousTrackButtonVisibility) {
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
   OverlayWindowViews* overlay_window = static_cast<OverlayWindowViews*>(
       window_controller()->GetWindowForTesting());
   ASSERT_TRUE(overlay_window);
@@ -2149,7 +2205,8 @@
 // Picture-in-Picture window controls are hidden.
 IN_PROC_BROWSER_TEST_F(MediaSessionPictureInPictureWindowControllerBrowserTest,
                        PreviousTrackButtonBounds) {
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
   OverlayWindowViews* overlay_window = static_cast<OverlayWindowViews*>(
       window_controller()->GetWindowForTesting());
   ASSERT_TRUE(overlay_window);
@@ -2175,7 +2232,8 @@
 // calls the Media Session Action "skipad" handler function.
 IN_PROC_BROWSER_TEST_F(MediaSessionPictureInPictureWindowControllerBrowserTest,
                        SkipAdHandlerCalled) {
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
   content::WebContents* active_web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   ASSERT_TRUE(content::ExecuteScript(active_web_contents, "video.play();"));
@@ -2195,7 +2253,8 @@
 // calls the Media Session actions "play" and "pause" handler functions.
 IN_PROC_BROWSER_TEST_F(MediaSessionPictureInPictureWindowControllerBrowserTest,
                        PlayPauseHandlersCalled) {
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
   content::WebContents* active_web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   ASSERT_TRUE(content::ExecuteScript(active_web_contents, "video.play();"));
@@ -2228,7 +2287,8 @@
 // calls the Media Session Action "nexttrack" handler function.
 IN_PROC_BROWSER_TEST_F(MediaSessionPictureInPictureWindowControllerBrowserTest,
                        NextTrackHandlerCalled) {
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
   content::WebContents* active_web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   ASSERT_TRUE(content::ExecuteScript(active_web_contents, "video.play();"));
@@ -2249,7 +2309,8 @@
 // window calls the Media Session Action "previoustrack" handler function.
 IN_PROC_BROWSER_TEST_F(MediaSessionPictureInPictureWindowControllerBrowserTest,
                        PreviousTrackHandlerCalled) {
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
   content::WebContents* active_web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   ASSERT_TRUE(content::ExecuteScript(active_web_contents, "video.play();"));
@@ -2283,8 +2344,7 @@
                        AutoEnterPictureInPictureIsNotTriggeredInRegularWebApp) {
   GURL test_page_url = ui_test_utils::GetTestUrl(
       base::FilePath(base::FilePath::kCurrentDirectory),
-      base::FilePath(
-          FILE_PATH_LITERAL("media/picture-in-picture/window-size.html")));
+      base::FilePath(kPictureInPictureWindowSizePage));
   ui_test_utils::NavigateToURL(browser(), test_page_url);
 
   content::WebContents* active_web_contents =
@@ -2318,8 +2378,7 @@
                        AutoExitPictureInPictureIsTriggeredInRegularWebApp) {
   GURL test_page_url = ui_test_utils::GetTestUrl(
       base::FilePath(base::FilePath::kCurrentDirectory),
-      base::FilePath(
-          FILE_PATH_LITERAL("media/picture-in-picture/window-size.html")));
+      base::FilePath(kPictureInPictureWindowSizePage));
   ui_test_utils::NavigateToURL(browser(), test_page_url);
 
   content::WebContents* active_web_contents =
@@ -2363,8 +2422,7 @@
                        AutoPictureInPictureTriggeredWhenFullscreen) {
   GURL test_page_url = ui_test_utils::GetTestUrl(
       base::FilePath(base::FilePath::kCurrentDirectory),
-      base::FilePath(
-          FILE_PATH_LITERAL("media/picture-in-picture/window-size.html")));
+      base::FilePath(kPictureInPictureWindowSizePage));
   ui_test_utils::NavigateToURL(browser(), test_page_url);
 
   content::WebContents* active_web_contents =
@@ -2804,8 +2862,7 @@
                        VideoWithNoAudioPausedWhenHiddenResumesPlayback) {
   GURL test_page_url = ui_test_utils::GetTestUrl(
       base::FilePath(base::FilePath::kCurrentDirectory),
-      base::FilePath(
-          FILE_PATH_LITERAL("media/picture-in-picture/window-size.html")));
+      base::FilePath(kPictureInPictureWindowSizePage));
   ui_test_utils::NavigateToURL(browser(), test_page_url);
 
   content::WebContents* active_web_contents =
@@ -2846,7 +2903,8 @@
 // event and resolves the callback.
 IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest,
                        ExitFireEventAndCallbackWhenNoSource) {
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
 
   content::WebContents* active_web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
@@ -2873,7 +2931,8 @@
 // experimental feature MuteButton is enabled.
 IN_PROC_BROWSER_TEST_F(MuteButtonPictureInPictureWindowControllerBrowserTest,
                        MuteButtonEnabled) {
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
 
   OverlayWindowViews* overlay_window = static_cast<OverlayWindowViews*>(
       window_controller()->GetWindowForTesting());
@@ -2992,7 +3051,8 @@
 // experimental feature MuteButton is disabled.
 IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest,
                        MuteButtonDisabled) {
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
 
   OverlayWindowViews* overlay_window = static_cast<OverlayWindowViews*>(
       window_controller()->GetWindowForTesting());
@@ -3054,7 +3114,8 @@
 // element is still notified.
 IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest,
                        ResetPlayerCloseWindowNotifiesElement) {
-  LoadTabAndEnterPictureInPicture(browser());
+  LoadTabAndEnterPictureInPicture(
+      browser(), base::FilePath(kPictureInPictureWindowSizePage));
   content::WebContents* active_web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
 
diff --git a/chrome/browser/plugins/flash_deprecation_infobar_delegate.cc b/chrome/browser/plugins/flash_deprecation_infobar_delegate.cc
index e50bf59..e69503df4 100644
--- a/chrome/browser/plugins/flash_deprecation_infobar_delegate.cc
+++ b/chrome/browser/plugins/flash_deprecation_infobar_delegate.cc
@@ -6,12 +6,13 @@
 
 #include "base/feature_list.h"
 #include "chrome/app/vector_icons/vector_icons.h"
-#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
 #include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/plugins/plugin_utils.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
+#include "components/content_settings/core/common/content_settings.h"
+#include "components/content_settings/core/common/content_settings_types.h"
 #include "components/infobars/core/infobar.h"
 #include "components/strings/grit/components_strings.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -19,24 +20,26 @@
 #include "url/url_constants.h"
 
 // static
-void FlashDeprecationInfoBarDelegate::Create(InfoBarService* infobar_service) {
+void FlashDeprecationInfoBarDelegate::Create(
+    InfoBarService* infobar_service,
+    HostContentSettingsMap* host_content_settings_map) {
   infobar_service->AddInfoBar(infobar_service->CreateConfirmInfoBar(
-      std::make_unique<FlashDeprecationInfoBarDelegate>()));
+      std::make_unique<FlashDeprecationInfoBarDelegate>(
+          host_content_settings_map)));
 }
 
 // static
 bool FlashDeprecationInfoBarDelegate::ShouldDisplayFlashDeprecation(
-    Profile* profile) {
-  DCHECK(profile);
+    HostContentSettingsMap* host_content_settings_map) {
+  DCHECK(host_content_settings_map);
 
   if (!base::FeatureList::IsEnabled(features::kFlashDeprecationWarning))
     return false;
 
   bool is_managed = false;
-  auto* settings_map = HostContentSettingsMapFactory::GetForProfile(profile);
   ContentSetting flash_setting =
-      PluginUtils::UnsafeGetRawDefaultFlashContentSetting(settings_map,
-                                                          &is_managed);
+      PluginUtils::UnsafeGetRawDefaultFlashContentSetting(
+          host_content_settings_map, &is_managed);
 
   // If the user can't do anything about their browser's Flash behavior,
   // there's no point to showing a Flash deprecation warning infobar.
@@ -47,6 +50,10 @@
   return flash_setting != CONTENT_SETTING_BLOCK;
 }
 
+FlashDeprecationInfoBarDelegate::FlashDeprecationInfoBarDelegate(
+    HostContentSettingsMap* host_content_settings_map)
+    : host_content_settings_map_(host_content_settings_map) {}
+
 infobars::InfoBarDelegate::InfoBarIdentifier
 FlashDeprecationInfoBarDelegate::GetIdentifier() const {
   return FLASH_DEPRECATION_INFOBAR_DELEGATE;
@@ -61,7 +68,23 @@
 }
 
 int FlashDeprecationInfoBarDelegate::GetButtons() const {
-  return BUTTON_NONE;
+  return BUTTON_OK;
+}
+
+base::string16 FlashDeprecationInfoBarDelegate::GetButtonLabel(
+    InfoBarButton button) const {
+  DCHECK_EQ(button, BUTTON_OK);
+  return l10n_util::GetStringUTF16(IDS_TURN_OFF);
+}
+
+bool FlashDeprecationInfoBarDelegate::Accept() {
+  // Can be nullptr in tests.
+  if (!host_content_settings_map_)
+    return true;
+
+  host_content_settings_map_->SetDefaultContentSetting(
+      CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_DEFAULT);
+  return true;
 }
 
 base::string16 FlashDeprecationInfoBarDelegate::GetLinkText() const {
diff --git a/chrome/browser/plugins/flash_deprecation_infobar_delegate.h b/chrome/browser/plugins/flash_deprecation_infobar_delegate.h
index b49fe90..e21dbd12 100644
--- a/chrome/browser/plugins/flash_deprecation_infobar_delegate.h
+++ b/chrome/browser/plugins/flash_deprecation_infobar_delegate.h
@@ -7,17 +7,21 @@
 
 #include "components/infobars/core/confirm_infobar_delegate.h"
 
+class HostContentSettingsMap;
 class InfoBarService;
-class Profile;
 
 class FlashDeprecationInfoBarDelegate : public ConfirmInfoBarDelegate {
  public:
-  static void Create(InfoBarService* infobar_service);
+  static void Create(InfoBarService* infobar_service,
+                     HostContentSettingsMap* host_content_settings_map);
 
-  // Returns true if we should display a deprecation warning for |profile|.
-  static bool ShouldDisplayFlashDeprecation(Profile* profile);
+  // Returns true if we should display a deprecation warning for
+  // |host_content_settings_map|.
+  static bool ShouldDisplayFlashDeprecation(
+      HostContentSettingsMap* host_content_settings_map);
 
-  FlashDeprecationInfoBarDelegate() = default;
+  explicit FlashDeprecationInfoBarDelegate(
+      HostContentSettingsMap* host_content_settings_map);
   ~FlashDeprecationInfoBarDelegate() override = default;
 
   // ConfirmInfobarDelegate:
@@ -25,8 +29,13 @@
   const gfx::VectorIcon& GetVectorIcon() const override;
   base::string16 GetMessageText() const override;
   int GetButtons() const override;
+  base::string16 GetButtonLabel(InfoBarButton button) const override;
+  bool Accept() override;
   base::string16 GetLinkText() const override;
   GURL GetLinkURL() const override;
+
+ private:
+  HostContentSettingsMap* const host_content_settings_map_;
 };
 
 #endif  // CHROME_BROWSER_PLUGINS_FLASH_DEPRECATION_INFOBAR_DELEGATE_H_
diff --git a/chrome/browser/printing/print_dialog_cloud.cc b/chrome/browser/printing/print_dialog_cloud.cc
index bd232cd..b3c70939 100644
--- a/chrome/browser/printing/print_dialog_cloud.cc
+++ b/chrome/browser/printing/print_dialog_cloud.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/printing/print_dialog_cloud.h"
 
-#include "base/bind.h"
 #include "base/macros.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/browser_process.h"
@@ -28,12 +27,8 @@
 
 class SignInObserver : public content::WebContentsObserver {
  public:
-  SignInObserver(content::WebContents* web_contents,
-                 const base::Closure& callback)
-      : WebContentsObserver(web_contents),
-        callback_(callback),
-        weak_ptr_factory_(this) {
-  }
+  explicit SignInObserver(content::WebContents* web_contents)
+      : WebContentsObserver(web_contents), weak_ptr_factory_(this) {}
 
  private:
   // Overridden from content::WebContentsObserver:
@@ -54,13 +49,10 @@
   void WebContentsDestroyed() override { delete this; }
 
   void OnSignIn() {
-    callback_.Run();
     if (web_contents())
       web_contents()->Close();
   }
 
-  GURL cloud_print_url_;
-  base::Closure callback_;
   base::WeakPtrFactory<SignInObserver> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(SignInObserver);
@@ -68,9 +60,7 @@
 
 }  // namespace
 
-void CreateCloudPrintSigninTab(Browser* browser,
-                               bool add_account,
-                               const base::Closure& callback) {
+void CreateCloudPrintSigninTab(Browser* browser, bool add_account) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (AccountConsistencyModeManager::IsMirrorEnabledForProfile(
           browser->profile())) {
@@ -88,7 +78,8 @@
                 url, g_browser_process->GetApplicationLocale()),
             content::Referrer(), WindowOpenDisposition::NEW_FOREGROUND_TAB,
             ui::PAGE_TRANSITION_AUTO_BOOKMARK, false));
-    new SignInObserver(web_contents, callback);
+    // This observer will delete itself after destroying the WebContents.
+    new SignInObserver(web_contents);
   }
 }
 
diff --git a/chrome/browser/printing/print_dialog_cloud.h b/chrome/browser/printing/print_dialog_cloud.h
index 5be0ba1..c94f7fc 100644
--- a/chrome/browser/printing/print_dialog_cloud.h
+++ b/chrome/browser/printing/print_dialog_cloud.h
@@ -7,8 +7,6 @@
 
 #include <string>
 
-#include "base/callback.h"
-
 class Browser;
 class Profile;
 
@@ -20,10 +18,7 @@
 
 // Creates a tab with Google 'sign in' or 'add account' page, based on
 // passed |add_account| value.
-// Calls |callback| when complete.
-void CreateCloudPrintSigninTab(Browser* browser,
-                               bool add_account,
-                               const base::Closure& callback);
+void CreateCloudPrintSigninTab(Browser* browser, bool add_account);
 
 // Parse switches from command_line and display the print dialog as appropriate.
 bool CreatePrintDialogFromCommandLine(Profile* profile,
diff --git a/chrome/browser/profiles/profile_manager_unittest.cc b/chrome/browser/profiles/profile_manager_unittest.cc
index 2e164d3e..fb54be05 100644
--- a/chrome/browser/profiles/profile_manager_unittest.cc
+++ b/chrome/browser/profiles/profile_manager_unittest.cc
@@ -153,8 +153,7 @@
     cl->AppendSwitch(switches::kTestType);
     wallpaper_controller_client_ =
         std::make_unique<WallpaperControllerClient>();
-    wallpaper_controller_client_->InitForTesting(
-        test_wallpaper_controller_.CreateInterfacePtr());
+    wallpaper_controller_client_->InitForTesting(&test_wallpaper_controller_);
 
     // Have to manually reset the session type in between test runs because
     // some tests log in users.
@@ -600,8 +599,7 @@
 
     wallpaper_controller_client_ =
         std::make_unique<WallpaperControllerClient>();
-    wallpaper_controller_client_->InitForTesting(
-        test_wallpaper_controller_.CreateInterfacePtr());
+    wallpaper_controller_client_->InitForTesting(&test_wallpaper_controller_);
 
     // Have to manually reset the session type in between test runs because
     // RegisterUser() changes it.
diff --git a/chrome/browser/resources/bookmarks/app.html b/chrome/browser/resources/bookmarks/app.html
index 93a5080f..59e496a 100644
--- a/chrome/browser/resources/bookmarks/app.html
+++ b/chrome/browser/resources/bookmarks/app.html
@@ -71,7 +71,7 @@
       bookmarks-folder-node {
         flex: 1;
         overflow-y: auto;
-        padding: 8px 3px 0 3px;
+        padding: 8px 3px 0 18px;
         user-select: none;
       }
 
diff --git a/chrome/browser/resources/bookmarks/folder_node.html b/chrome/browser/resources/bookmarks/folder_node.html
index 80ed7c1..c8ddfd3 100644
--- a/chrome/browser/resources/bookmarks/folder_node.html
+++ b/chrome/browser/resources/bookmarks/folder_node.html
@@ -12,33 +12,44 @@
   <template>
     <style include="shared-style">
       :host {
-        --padding-start-per-depth: 36px;
         display: block;
       }
 
-      .v-centered {
+      #container {
         align-items: center;
-        display: flex;
-        flex-direction: row;
+        cursor: pointer;
+        display: grid;
+        grid-template-areas: 'arrow folder label';
+        grid-template-columns: 24px 24px auto;
+        height: 40px;
+        min-width: fit-content;
+        overflow: hidden;
+        padding-inline-start: calc(var(--node-depth, 0) * 10px);
+      }
+
+      #arrow {
+        grid-area: arrow;
+        justify-self: center;
+        margin: 0;
+        --cr-icon-button-size: 40px;
+      }
+
+      #arrow:not([is-open]) {
+        transform: rotate(-90deg);
+        transition: transform 150ms;
+      }
+
+      .folder-icon {
+        grid-area: folder;
+        justify-self: center;
       }
 
       .menu-label {
         color: var(--folder-inactive-color);
         font-weight: 500;
-        margin-inline-start: 16px;
-      }
-
-      #container {
-        cursor: pointer;
-        height: 40px;
-        padding-inline-start:
-            calc(var(--node-depth, 0) * var(--padding-start-per-depth));
-        position: relative;
-      }
-
-      #folder-label {
-        flex-grow: 1;
-        padding-inline-end: 8px;
+        grid-area: label;
+        padding: 0 6px;
+        white-space: nowrap;
       }
 
       :host([is-selected-folder_]) .menu-label,
@@ -52,15 +63,6 @@
         color: var(--google-grey-refresh-700);
       }
 
-      #arrow {
-        margin: 0 8px;
-      }
-
-      #arrow:not([is-open]) {
-        transform: rotate(-90deg);
-        transition: transform 150ms;
-      }
-
       :host-context([dir='rtl']) #arrow:not([is-open]) {
         transform: rotate(90deg);
       }
@@ -68,14 +70,9 @@
       #arrow[is-open] {
         transform: initial;
       }
-
-      [no-children] {
-        margin-inline-start: 52px; /* The width of the arrow and its margin */
-      }
     </style>
 
     <div id="container"
-        class="v-centered"
         on-click="selectFolder_"
         on-dblclick="toggleFolder_"
         on-contextmenu="onContextMenu_"
@@ -89,14 +86,12 @@
             tabindex="-1" is-open$="[[isOpen]]" noink aria-hidden="true">
         </cr-icon-button>
       </template>
-      <div id="folder-label" class="v-centered">
-        <div class="folder-icon"
-            open$="[[isSelectedFolder_]]"
-            no-children$="[[!hasChildFolder_]]">
-        </div>
-        <div class="menu-label elided-text" title="[[item_.title]]">
-          [[item_.title]]
-        </div>
+      <div class="folder-icon"
+          open$="[[isSelectedFolder_]]"
+          no-children$="[[!hasChildFolder_]]">
+      </div>
+      <div class="menu-label" title="[[item_.title]]">
+        [[item_.title]]
       </div>
     </div>
     <div id="descendants" role="group">
diff --git a/chrome/browser/resources/bookmarks/item.html b/chrome/browser/resources/bookmarks/item.html
index 9eb10af..ec8610f1 100644
--- a/chrome/browser/resources/bookmarks/item.html
+++ b/chrome/browser/resources/bookmarks/item.html
@@ -80,6 +80,12 @@
       :host(:focus) {
         z-index: 1;
       }
+
+      .elided-text {
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+      }
     </style>
     <div id="icon"></div>
     <div id="website-title" class="elided-text" title="[[item_.title]]">
diff --git a/chrome/browser/resources/bookmarks/shared_style.html b/chrome/browser/resources/bookmarks/shared_style.html
index e2a3a53..918778c 100644
--- a/chrome/browser/resources/bookmarks/shared_style.html
+++ b/chrome/browser/resources/bookmarks/shared_style.html
@@ -72,12 +72,6 @@
         margin: 2px;
         width: 16px;
       }
-
-      .elided-text {
-        overflow: hidden;
-        text-overflow: ellipsis;
-        white-space: nowrap;
-      }
     </style>
   </template>
 </dom-module>
diff --git a/chrome/browser/resources/print_preview/native_layer.js b/chrome/browser/resources/print_preview/native_layer.js
index 083782cf..da69df1 100644
--- a/chrome/browser/resources/print_preview/native_layer.js
+++ b/chrome/browser/resources/print_preview/native_layer.js
@@ -279,15 +279,13 @@
     }
 
     /**
-     * Opens the Google Cloud Print sign-in tab. The DESTINATIONS_RELOAD event
-     *     will be dispatched in response.
+     * Opens the Google Cloud Print sign-in tab. If the user signs in
+     * successfully, the user-accounts-updated event will be sent in response.
      * @param {boolean} addAccount Whether to open an 'add a new account' or
      *     default sign in page.
-     * @return {!Promise} Promise that resolves when the sign in tab has been
-     *     closed and the destinations should be reloaded.
      */
     signIn(addAccount) {
-      return cr.sendWithPromise('signIn', addAccount);
+      chrome.send('signIn', [addAccount]);
     }
 
     /**
diff --git a/chrome/browser/resources/print_preview/ui/destination_dialog.js b/chrome/browser/resources/print_preview/ui/destination_dialog.js
index 7bfeb68..b1b514d 100644
--- a/chrome/browser/resources/print_preview/ui/destination_dialog.js
+++ b/chrome/browser/resources/print_preview/ui/destination_dialog.js
@@ -288,9 +288,7 @@
   onSignInClick_: function() {
     this.metrics_.record(
         print_preview.Metrics.DestinationSearchBucket.SIGNIN_TRIGGERED);
-    print_preview.NativeLayer.getInstance().signIn(false).then(() => {
-      this.destinationStore.onDestinationsReload();
-    });
+    print_preview.NativeLayer.getInstance().signIn(false);
   },
 
   /** @private */
@@ -380,9 +378,7 @@
       this.metrics_.record(
           print_preview.Metrics.DestinationSearchBucket.ACCOUNT_CHANGED);
     } else {
-      print_preview.NativeLayer.getInstance().signIn(true).then(
-          this.destinationStore.onDestinationsReload.bind(
-              this.destinationStore));
+      print_preview.NativeLayer.getInstance().signIn(true);
       const options = select.querySelectorAll('option');
       for (let i = 0; i < options.length; i++) {
         if (options[i].value == this.activeUser) {
diff --git a/chrome/browser/resources/safe_browsing/download_file_types.asciipb b/chrome/browser/resources/safe_browsing/download_file_types.asciipb
index b0532e9..b0fdb39 100644
--- a/chrome/browser/resources/safe_browsing/download_file_types.asciipb
+++ b/chrome/browser/resources/safe_browsing/download_file_types.asciipb
@@ -8,7 +8,7 @@
 ##
 ## Top level settings
 ##
-version_id: 36
+version_id: 37
 sampled_ping_probability: 0.01
 max_archived_binaries_to_report: 10
 default_file_type {
@@ -706,7 +706,7 @@
   ping_setting: FULL_PING
   inspection_type: ZIP
   platform_settings {
-    max_file_size_to_analyze: 15728640 # 15MB
+    max_file_size_to_analyze: 52428800 # 50MB
   }
 }
 file_types {
diff --git a/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html b/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html
index bc19488..5245009 100644
--- a/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html
+++ b/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html
@@ -115,7 +115,8 @@
     </settings-toggle-button>
     <settings-toggle-button
         pref="{{prefs.settings.a11y.virtual_keyboard}}"
-        label="$i18n{onScreenKeyboardLabel}">
+        label="$i18n{onScreenKeyboardLabel}"
+        hidden$="[[prefs.ash.kiosk_next_shell.enabled.value]]">
     </settings-toggle-button>
     <settings-toggle-button
         pref="{{prefs.settings.a11y.dictation}}"
diff --git a/chrome/browser/resources/settings/device_page/stylus.html b/chrome/browser/resources/settings/device_page/stylus.html
index 7dad79f1..6ec8eee 100644
--- a/chrome/browser/resources/settings/device_page/stylus.html
+++ b/chrome/browser/resources/settings/device_page/stylus.html
@@ -35,7 +35,8 @@
     <settings-toggle-button id="enableStylusToolsToggle"
         class="continuation"
         pref="{{prefs.settings.enable_stylus_tools}}"
-        label="$i18n{stylusEnableStylusTools}">
+        label="$i18n{stylusEnableStylusTools}"
+        hidden$="[[prefs.ash.kiosk_next_shell.enabled.value]]">
     </settings-toggle-button>
 
     <template is="dom-if" if="[[hasInternalStylus_]]">
@@ -43,7 +44,8 @@
           id ="launchPaletteOnEjectEventToggle"
           pref="{{prefs.settings.launch_palette_on_eject_event}}"
           label="$i18n{stylusAutoOpenStylusTools}"
-          disabled="[[!prefs.settings.enable_stylus_tools.value]]">
+          disabled="[[!prefs.settings.enable_stylus_tools.value]]"
+          hidden$="[[prefs.ash.kiosk_next_shell.enabled.value]]">
       </settings-toggle-button>
     </template>
 
diff --git a/chrome/browser/resources/settings/languages_page/languages_page.html b/chrome/browser/resources/settings/languages_page/languages_page.html
index 911bd906..0cd5425 100644
--- a/chrome/browser/resources/settings/languages_page/languages_page.html
+++ b/chrome/browser/resources/settings/languages_page/languages_page.html
@@ -286,7 +286,8 @@
           </div>
           <settings-toggle-button
               pref="{{prefs.settings.language.ime_menu_activated}}"
-              label="$i18n{showImeMenu}">
+              label="$i18n{showImeMenu}"
+              hidden$="[[prefs.ash.kiosk_next_shell.enabled.value]]">
           </settings-toggle-button>
         </iron-collapse>
 </if>
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/google_apps/nux_google_apps.html b/chrome/browser/resources/welcome/onboarding_welcome/google_apps/nux_google_apps.html
index 11cb48b5..4416a947 100644
--- a/chrome/browser/resources/welcome/onboarding_welcome/google_apps/nux_google_apps.html
+++ b/chrome/browser/resources/welcome/onboarding_welcome/google_apps/nux_google_apps.html
@@ -166,8 +166,8 @@
 
       .news {
         content: -webkit-image-set(
-            url(chrome://theme/IDS_ONBOARDING_WELCOME_MAPS@1x) 1x,
-            url(chrome://theme/IDS_ONBOARDING_WELCOME_MAPS@2x) 2x);
+            url(chrome://theme/IDS_ONBOARDING_WELCOME_NEWS@1x) 1x,
+            url(chrome://theme/IDS_ONBOARDING_WELCOME_NEWS@2x) 2x);
       }
 
       .search {
diff --git a/chrome/browser/service_process/service_process_control.cc b/chrome/browser/service_process/service_process_control.cc
index ff6af0f5..e8c00e0e 100644
--- a/chrome/browser/service_process/service_process_control.cc
+++ b/chrome/browser/service_process/service_process_control.cc
@@ -281,11 +281,6 @@
   DCHECK(!histograms_callback.is_null());
   histograms_callback_.Reset();
 
-#if defined(OS_MACOSX)
-  // TODO(vitalybuka): Investigate why it crashes MAC http://crbug.com/406227.
-  return false;
-#endif  // OS_MACOSX
-
   // If the service process is already running then connect to it.
   if (!CheckServiceProcessReady())
     return false;
diff --git a/chrome/browser/service_process/service_process_control_browsertest.cc b/chrome/browser/service_process/service_process_control_browsertest.cc
index 4924c77..6f04053 100644
--- a/chrome/browser/service_process/service_process_control_browsertest.cc
+++ b/chrome/browser/service_process/service_process_control_browsertest.cc
@@ -418,16 +418,7 @@
       base::TimeDelta()));
 }
 
-// Histograms disabled on OSX http://crbug.com/406227
-#if defined(OS_MACOSX)
-#define MAYBE_HistogramsTimeout DISABLED_HistogramsTimeout
-#define MAYBE_Histograms DISABLED_Histograms
-#else
-#define MAYBE_HistogramsTimeout HistogramsTimeout
-#define MAYBE_Histograms Histograms
-#endif
-IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest,
-                       MAYBE_HistogramsTimeout) {
+IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, HistogramsTimeout) {
   LaunchServiceProcessControlAndWait();
   ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
   // Callback should not be called during GetHistograms call.
@@ -442,7 +433,7 @@
   run_loop.Run();
 }
 
-IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, MAYBE_Histograms) {
+IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, Histograms) {
   LaunchServiceProcessControlAndWait();
   ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
   // Callback should not be called during GetHistograms call.
diff --git a/chrome/browser/sync/test/integration/bookmarks_helper.h b/chrome/browser/sync/test/integration/bookmarks_helper.h
index 4637207..5902c17 100644
--- a/chrome/browser/sync/test/integration/bookmarks_helper.h
+++ b/chrome/browser/sync/test/integration/bookmarks_helper.h
@@ -13,8 +13,8 @@
 #include "chrome/browser/sync/test/integration/await_match_status_change_checker.h"
 #include "chrome/browser/sync/test/integration/multi_client_status_change_checker.h"
 #include "chrome/browser/sync/test/integration/single_client_status_change_checker.h"
-#include "components/sync/base/cryptographer.h"
 #include "components/sync/engine_impl/loopback_server/loopback_server_entity.h"
+#include "components/sync/nigori/cryptographer.h"
 #include "components/sync/test/fake_server/fake_server.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "url/gurl.h"
diff --git a/chrome/browser/sync/test/integration/encryption_helper.h b/chrome/browser/sync/test/integration/encryption_helper.h
index 9cbc283..aa4cf09b 100644
--- a/chrome/browser/sync/test/integration/encryption_helper.h
+++ b/chrome/browser/sync/test/integration/encryption_helper.h
@@ -9,7 +9,7 @@
 
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/sync/test/integration/single_client_status_change_checker.h"
-#include "components/sync/base/cryptographer.h"
+#include "components/sync/nigori/cryptographer.h"
 #include "components/sync/protocol/nigori_specifics.pb.h"
 #include "components/sync/test/fake_server/fake_server.h"
 
diff --git a/chrome/browser/sync/test/integration/single_client_custom_passphrase_sync_test.cc b/chrome/browser/sync/test/integration/single_client_custom_passphrase_sync_test.cc
index b440d80..3017e27 100644
--- a/chrome/browser/sync/test/integration/single_client_custom_passphrase_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_custom_passphrase_sync_test.cc
@@ -5,10 +5,10 @@
 #include "chrome/browser/sync/test/integration/bookmarks_helper.h"
 #include "chrome/browser/sync/test/integration/encryption_helper.h"
 #include "chrome/browser/sync/test/integration/sync_test.h"
-#include "components/sync/base/cryptographer.h"
 #include "components/sync/base/passphrase_enums.h"
 #include "components/sync/base/system_encryptor.h"
 #include "components/sync/driver/profile_sync_service.h"
+#include "components/sync/nigori/cryptographer.h"
 
 namespace {
 
diff --git a/chrome/browser/sync/test/integration/single_client_nigori_sync_test.cc b/chrome/browser/sync/test/integration/single_client_nigori_sync_test.cc
index a6bda83a..03a2d27 100644
--- a/chrome/browser/sync/test/integration/single_client_nigori_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_nigori_sync_test.cc
@@ -6,7 +6,7 @@
 #include "base/macros.h"
 #include "chrome/browser/sync/test/integration/encryption_helper.h"
 #include "chrome/browser/sync/test/integration/sync_test.h"
-#include "components/sync/base/nigori.h"
+#include "components/sync/nigori/nigori.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
 namespace {
diff --git a/chrome/browser/sync/test/integration/two_client_send_tab_to_self_sync_test.cc b/chrome/browser/sync/test/integration/two_client_send_tab_to_self_sync_test.cc
index 13b8f3a..40a74778 100644
--- a/chrome/browser/sync/test/integration/two_client_send_tab_to_self_sync_test.cc
+++ b/chrome/browser/sync/test/integration/two_client_send_tab_to_self_sync_test.cc
@@ -12,6 +12,7 @@
 #include "chrome/browser/sync/test/integration/sync_test.h"
 #include "components/history/core/browser/history_service.h"
 #include "components/send_tab_to_self/features.h"
+#include "components/send_tab_to_self/send_tab_to_self_bridge.h"
 #include "components/send_tab_to_self/send_tab_to_self_model.h"
 #include "components/send_tab_to_self/send_tab_to_self_sync_service.h"
 #include "components/send_tab_to_self/target_device_info.h"
@@ -206,6 +207,18 @@
                       ->GetDeviceInfoTracker())
                   .Wait());
 
+  // Explicitly set the two profiles to have different client names to simulate
+  // them being on different devices. Otherwise their device infos will get
+  // deduped.
+  static_cast<send_tab_to_self::SendTabToSelfBridge*>(
+      SendTabToSelfSyncServiceFactory::GetForProfile(GetProfile(0))
+          ->GetSendTabToSelfModel())
+      ->SetLocalDeviceNameForTest("device1");
+  static_cast<send_tab_to_self::SendTabToSelfBridge*>(
+      SendTabToSelfSyncServiceFactory::GetForProfile(GetProfile(1))
+          ->GetSendTabToSelfModel())
+      ->SetLocalDeviceNameForTest("device2");
+
   std::map<std::string, send_tab_to_self::TargetDeviceInfo>
       profile1_target_device_map =
           SendTabToSelfSyncServiceFactory::GetForProfile(GetProfile(0))
diff --git a/chrome/browser/task_manager/task_manager_browsertest.cc b/chrome/browser/task_manager/task_manager_browsertest.cc
index 02d0d90..c773ee1 100644
--- a/chrome/browser/task_manager/task_manager_browsertest.cc
+++ b/chrome/browser/task_manager/task_manager_browsertest.cc
@@ -51,6 +51,7 @@
 #include "extensions/common/extension.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
+#include "services/strings/grit/services_strings.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -801,7 +802,7 @@
   model()->ToggleColumnVisibility(ColumnSpecifier::V8_MEMORY);
 
   auto proxy_resolver_name =
-      l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_PROXY_RESOLVER_NAME);
+      l10n_util::GetStringUTF16(IDS_PROXY_RESOLVER_DISPLAY_NAME);
   ui_test_utils::NavigateToURL(browser(), GetTestURL());
   // The PAC script is trivial, so don't expect a large heap.
   size_t minimal_heap_size = 1024;
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 533f68b..1f1a5314 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -2207,6 +2207,7 @@
     deps += [
       "//chrome/browser/apps/app_shim",
       "//components/remote_cocoa/app_shim",
+      "//components/remote_cocoa/browser",
       "//extensions/components/native_app_window",
       "//third_party/google_toolbox_for_mac",
       "//third_party/mozilla",
diff --git a/chrome/browser/ui/app_list/OWNERS b/chrome/browser/ui/app_list/OWNERS
index 7738f20..301ef10 100644
--- a/chrome/browser/ui/app_list/OWNERS
+++ b/chrome/browser/ui/app_list/OWNERS
@@ -7,3 +7,4 @@
 per-file app_launch_event_logger*=charleszhao@chromium.org
 per-file app_launch_event_logger*=jiameng@chromium.org
 
+# COMPONENT: UI>Shell>Launcher
diff --git a/chrome/browser/ui/app_list/extension_app_context_menu.cc b/chrome/browser/ui/app_list/extension_app_context_menu.cc
index 2d83f5b..f806903 100644
--- a/chrome/browser/ui/app_list/extension_app_context_menu.cc
+++ b/chrome/browser/ui/app_list/extension_app_context_menu.cc
@@ -12,6 +12,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/app_list/app_context_menu_delegate.h"
 #include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
+#include "chrome/browser/ui/app_list/extension_app_utils.h"
 #include "chrome/browser/web_applications/system_web_app_manager.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/grit/chromium_strings.h"
@@ -106,6 +107,12 @@
         base::string16(),
         &index,
         false);  // is_action_menu
+
+    const int appended_count = index - ash::USE_LAUNCH_TYPE_COMMAND_END;
+    AddMenuItemIconsForSystemApps(app_id(), menu_model,
+                                  menu_model->GetItemCount() - appended_count,
+                                  appended_count);
+
     if (!is_platform_app_)
       AddContextMenuOption(menu_model, ash::OPTIONS, IDS_NEW_TAB_APP_OPTIONS);
 
diff --git a/chrome/browser/ui/app_list/extension_app_utils.cc b/chrome/browser/ui/app_list/extension_app_utils.cc
index 7421e77..9affea2 100644
--- a/chrome/browser/ui/app_list/extension_app_utils.cc
+++ b/chrome/browser/ui/app_list/extension_app_utils.cc
@@ -7,7 +7,14 @@
 #include "chrome/browser/chromeos/login/demo_mode/demo_session.h"
 #include "chrome/browser/extensions/extension_ui_util.h"
 #include "chrome/common/extensions/extension_constants.h"
+#include "chrome/grit/generated_resources.h"
+#include "extensions/common/constants.h"
 #include "extensions/common/extension.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/models/simple_menu_model.h"
+#include "ui/gfx/paint_vector_icon.h"
+#include "ui/views/controls/menu/menu_config.h"
+#include "ui/views/vector_icons.h"
 
 namespace app_list {
 
@@ -34,4 +41,24 @@
   return false;
 }
 
+void AddMenuItemIconsForSystemApps(const std::string& app_id,
+                                   ui::SimpleMenuModel* menu_model,
+                                   int start_index,
+                                   int count) {
+  if (app_id != extension_misc::kFilesManagerAppId)
+    return;
+
+  for (int i = 0; i < count; ++i) {
+    const int index = start_index + i;
+    if (menu_model->GetLabelAt(index) ==
+        l10n_util::GetStringUTF16(IDS_APP_LIST_CONTEXT_MENU_NEW_WINDOW)) {
+      const views::MenuConfig& menu_config = views::MenuConfig::instance();
+      menu_model->SetIcon(
+          index, gfx::Image(gfx::CreateVectorIcon(
+                     views::kNewWindowIcon, menu_config.touchable_icon_size,
+                     menu_config.touchable_icon_color)));
+    }
+  }
+}
+
 }  // namespace app_list
diff --git a/chrome/browser/ui/app_list/extension_app_utils.h b/chrome/browser/ui/app_list/extension_app_utils.h
index b426389..e2a7bf0 100644
--- a/chrome/browser/ui/app_list/extension_app_utils.h
+++ b/chrome/browser/ui/app_list/extension_app_utils.h
@@ -15,12 +15,24 @@
 class Extension;
 }
 
+namespace ui {
+class SimpleMenuModel;
+}
+
 namespace app_list {
 
 bool ShouldShowInLauncher(const extensions::Extension* extension,
                           content::BrowserContext* context);
 bool HideInLauncherById(std::string extension_id);
 
+// chrome.contextMenus API does not support menu item icons. This function
+// compensates for that by adding icons to menus for prominent system apps
+// (currently just Files app)
+void AddMenuItemIconsForSystemApps(const std::string& app_id,
+                                   ui::SimpleMenuModel* menu_model,
+                                   int start_index,
+                                   int count);
+
 }  // namespace app_list
 
 #endif  // CHROME_BROWSER_UI_APP_LIST_EXTENSION_APP_UTILS_H_
diff --git a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider.cc b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider.cc
index 2c4e83d95..33f82440 100644
--- a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider.cc
+++ b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider.cc
@@ -96,6 +96,11 @@
 ArcPlayStoreSearchProvider::~ArcPlayStoreSearchProvider() = default;
 
 void ArcPlayStoreSearchProvider::Start(const base::string16& query) {
+  last_query_ = query;
+
+  // Clear any results from the previous query.
+  ClearResultsSilently();
+
   arc::mojom::AppInstance* app_instance =
       arc::ArcServiceManager::Get()
           ? ARC_GET_INSTANCE_FOR_METHOD(
@@ -104,17 +109,18 @@
           : nullptr;
 
   if (app_instance == nullptr || query.empty()) {
-    ClearResults();
     return;
   }
 
   app_instance->GetRecentAndSuggestedAppsFromPlayStore(
       base::UTF16ToUTF8(query), max_results_,
       base::Bind(&ArcPlayStoreSearchProvider::OnResults,
-                 weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now()));
+                 weak_ptr_factory_.GetWeakPtr(), query,
+                 base::TimeTicks::Now()));
 }
 
 void ArcPlayStoreSearchProvider::OnResults(
+    const base::string16& query,
     base::TimeTicks query_start_time,
     arc::ArcPlayStoreSearchRequestState state,
     std::vector<arc::mojom::AppDiscoveryResultPtr> results) {
@@ -122,7 +128,17 @@
     DCHECK(results.empty());
     UMA_HISTOGRAM_ENUMERATION(kAppListPlayStoreQueryStateHistogram, state,
                               arc::ArcPlayStoreSearchRequestState::STATE_COUNT);
-    ClearResults();
+    return;
+  }
+
+  // Play store could have a long latency that when the results come back,
+  // user has entered a different query. Do not return the staled results
+  // from the previous query in such case.
+  if (query != last_query_) {
+    UMA_HISTOGRAM_ENUMERATION(
+        kAppListPlayStoreQueryStateHistogram,
+        arc::ArcPlayStoreSearchRequestState::FAILED_TO_CALL_CANCEL,
+        arc::ArcPlayStoreSearchRequestState::STATE_COUNT);
     return;
   }
 
@@ -134,7 +150,6 @@
           kAppListPlayStoreQueryStateHistogram,
           arc::ArcPlayStoreSearchRequestState::CHROME_GOT_INVALID_RESULT,
           arc::ArcPlayStoreSearchRequestState::STATE_COUNT);
-      ClearResults();
       return;
     }
 
diff --git a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider.h b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider.h
index 5aaf9f9..bed643b 100644
--- a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider.h
+++ b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider.h
@@ -32,13 +32,15 @@
   void Start(const base::string16& query) override;
 
  private:
-  void OnResults(base::TimeTicks query_start_time,
+  void OnResults(const base::string16& query,
+                 base::TimeTicks query_start_time,
                  arc::ArcPlayStoreSearchRequestState state,
                  std::vector<arc::mojom::AppDiscoveryResultPtr> results);
 
   const int max_results_;
   Profile* const profile_;                            // Owned by ProfileInfo.
   AppListControllerDelegate* const list_controller_;  // Owned by AppListClient.
+  base::string16 last_query_;  // Most recent query issued.
   base::WeakPtrFactory<ArcPlayStoreSearchProvider> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(ArcPlayStoreSearchProvider);
diff --git a/chrome/browser/ui/ash/launcher/OWNERS b/chrome/browser/ui/ash/launcher/OWNERS
index b051bca2..e90111b8 100644
--- a/chrome/browser/ui/ash/launcher/OWNERS
+++ b/chrome/browser/ui/ash/launcher/OWNERS
@@ -1,3 +1,5 @@
 skuhne@chromium.org
 stevenjb@chromium.org
 khmel@chromium.org
+
+# COMPONENTS: UI>Shell>Shelf
\ No newline at end of file
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
index bd6aa73..1ed2b24 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
@@ -1048,8 +1048,7 @@
     // Initialize WallpaperControllerClient.
     wallpaper_controller_client_ =
         std::make_unique<WallpaperControllerClient>();
-    wallpaper_controller_client_->InitForTesting(
-        test_wallpaper_controller_.CreateInterfacePtr());
+    wallpaper_controller_client_->InitForTesting(&test_wallpaper_controller_);
 
     // AvatarMenu and multiple profiles works after user logged in.
     profile_manager()->SetLoggedIn(true);
diff --git a/chrome/browser/ui/ash/launcher/extension_launcher_context_menu.cc b/chrome/browser/ui/ash/launcher/extension_launcher_context_menu.cc
index 5783b8b..4a02829 100644
--- a/chrome/browser/ui/ash/launcher/extension_launcher_context_menu.cc
+++ b/chrome/browser/ui/ash/launcher/extension_launcher_context_menu.cc
@@ -13,6 +13,7 @@
 #include "chrome/browser/extensions/launch_util.h"
 #include "chrome/browser/prefs/incognito_mode_prefs.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/app_list/extension_app_utils.h"
 #include "chrome/browser/ui/ash/launcher/browser_shortcut_launcher_item_controller.h"
 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.h"
@@ -214,6 +215,9 @@
       int index = 0;
       extension_items_->AppendExtensionItems(app_key, base::string16(), &index,
                                              false);  // is_action_menu
+      app_list::AddMenuItemIconsForSystemApps(
+          item().id.app_id, menu_model, menu_model->GetItemCount() - index,
+          index);
     }
   }
 }
diff --git a/chrome/browser/ui/ash/multi_user/multi_profile_support_unittest.cc b/chrome/browser/ui/ash/multi_user/multi_profile_support_unittest.cc
index 4123c2a..99292b8 100644
--- a/chrome/browser/ui/ash/multi_user/multi_profile_support_unittest.cc
+++ b/chrome/browser/ui/ash/multi_user/multi_profile_support_unittest.cc
@@ -278,7 +278,7 @@
 
   user_manager::ScopedUserManager user_manager_enabler_;
 
-  std::unique_ptr<WallpaperControllerClient> wallpaper_controller_client_;
+  std::unique_ptr<::WallpaperControllerClient> wallpaper_controller_client_;
 
   TestWallpaperController test_wallpaper_controller_;
 
@@ -315,9 +315,9 @@
       AccountId::FromUserEmail("A"));
   ash::MultiUserWindowManagerImpl::Get()->SetAnimationSpeedForTest(
       ash::MultiUserWindowManagerImpl::ANIMATION_SPEED_DISABLED);
-  wallpaper_controller_client_ = std::make_unique<WallpaperControllerClient>();
-  wallpaper_controller_client_->InitForTesting(
-      test_wallpaper_controller_.CreateInterfacePtr());
+  wallpaper_controller_client_ =
+      std::make_unique<::WallpaperControllerClient>();
+  wallpaper_controller_client_->InitForTesting(&test_wallpaper_controller_);
 }
 
 void MultiProfileSupportTest::TearDown() {
diff --git a/chrome/browser/ui/ash/test_wallpaper_controller.cc b/chrome/browser/ui/ash/test_wallpaper_controller.cc
index 118e8e7..7d38d18 100644
--- a/chrome/browser/ui/ash/test_wallpaper_controller.cc
+++ b/chrome/browser/ui/ash/test_wallpaper_controller.cc
@@ -4,32 +4,24 @@
 
 #include "chrome/browser/ui/ash/test_wallpaper_controller.h"
 
-constexpr uint32_t dummy_image_id = 1;
+#include "ash/public/cpp/wallpaper_controller_observer.h"
 
-TestWallpaperController::TestWallpaperController() : binding_(this) {}
+TestWallpaperController::TestWallpaperController() = default;
 
 TestWallpaperController::~TestWallpaperController() = default;
 
 void TestWallpaperController::ShowWallpaperImage(const gfx::ImageSkia& image) {
   current_wallpaper = image;
-  test_observers_.ForAllPtrs([](ash::mojom::WallpaperObserver* observer) {
-    observer->OnWallpaperChanged(dummy_image_id);
-  });
+  for (auto& observer : observers_)
+    observer.OnWallpaperChanged();
 }
 
 void TestWallpaperController::ClearCounts() {
   remove_user_wallpaper_count_ = 0;
 }
 
-ash::mojom::WallpaperControllerPtr
-TestWallpaperController::CreateInterfacePtr() {
-  ash::mojom::WallpaperControllerPtr ptr;
-  binding_.Bind(mojo::MakeRequest(&ptr));
-  return ptr;
-}
-
 void TestWallpaperController::Init(
-    ash::mojom::WallpaperControllerClientPtr client,
+    ash::WallpaperControllerClient* client,
     const base::FilePath& user_data_path,
     const base::FilePath& chromeos_wallpapers_path,
     const base::FilePath& chromeos_custom_wallpapers_path,
@@ -38,7 +30,7 @@
 }
 
 void TestWallpaperController::SetCustomWallpaper(
-    ash::mojom::WallpaperUserInfoPtr user_info,
+    const ash::WallpaperUserInfo& user_info,
     const std::string& wallpaper_files_id,
     const std::string& file_name,
     ash::WallpaperLayout layout,
@@ -48,17 +40,16 @@
 }
 
 void TestWallpaperController::SetOnlineWallpaperIfExists(
-    ash::mojom::WallpaperUserInfoPtr user_info,
+    const ash::WallpaperUserInfo& user_info,
     const std::string& url,
     ash::WallpaperLayout layout,
     bool preview_mode,
-    ash::mojom::WallpaperController::SetOnlineWallpaperIfExistsCallback
-        callback) {
+    SetOnlineWallpaperIfExistsCallback callback) {
   NOTIMPLEMENTED();
 }
 
 void TestWallpaperController::SetOnlineWallpaperFromData(
-    ash::mojom::WallpaperUserInfoPtr user_info,
+    const ash::WallpaperUserInfo& user_info,
     const std::string& image_data,
     const std::string& url,
     ash::WallpaperLayout layout,
@@ -68,7 +59,7 @@
 }
 
 void TestWallpaperController::SetDefaultWallpaper(
-    ash::mojom::WallpaperUserInfoPtr user_info,
+    const ash::WallpaperUserInfo& user_info,
     const std::string& wallpaper_files_id,
     bool show_wallpaper) {
   ++set_default_wallpaper_count_;
@@ -81,7 +72,7 @@
 }
 
 void TestWallpaperController::SetPolicyWallpaper(
-    ash::mojom::WallpaperUserInfoPtr user_info,
+    const ash::WallpaperUserInfo& user_info,
     const std::string& wallpaper_files_id,
     const std::string& data) {
   NOTIMPLEMENTED();
@@ -92,15 +83,14 @@
   NOTIMPLEMENTED();
 }
 
-void TestWallpaperController::SetThirdPartyWallpaper(
-    ash::mojom::WallpaperUserInfoPtr user_info,
+bool TestWallpaperController::SetThirdPartyWallpaper(
+    const ash::WallpaperUserInfo& user_info,
     const std::string& wallpaper_files_id,
     const std::string& file_name,
     ash::WallpaperLayout layout,
-    const gfx::ImageSkia& image,
-    ash::mojom::WallpaperController::SetThirdPartyWallpaperCallback callback) {
-  std::move(callback).Run(true /*allowed=*/, dummy_image_id);
+    const gfx::ImageSkia& image) {
   ShowWallpaperImage(image);
+  return true;
 }
 
 void TestWallpaperController::ConfirmPreviewWallpaper() {
@@ -112,13 +102,13 @@
 }
 
 void TestWallpaperController::UpdateCustomWallpaperLayout(
-    ash::mojom::WallpaperUserInfoPtr user_info,
+    const ash::WallpaperUserInfo& user_info,
     ash::WallpaperLayout layout) {
   NOTIMPLEMENTED();
 }
 
 void TestWallpaperController::ShowUserWallpaper(
-    ash::mojom::WallpaperUserInfoPtr user_info) {
+    const ash::WallpaperUserInfo& user_info) {
   NOTIMPLEMENTED();
 }
 
@@ -141,19 +131,19 @@
 }
 
 void TestWallpaperController::RemoveUserWallpaper(
-    ash::mojom::WallpaperUserInfoPtr user_info,
+    const ash::WallpaperUserInfo& user_info,
     const std::string& wallpaper_files_id) {
   ++remove_user_wallpaper_count_;
 }
 
 void TestWallpaperController::RemovePolicyWallpaper(
-    ash::mojom::WallpaperUserInfoPtr user_info,
+    const ash::WallpaperUserInfo& user_info,
     const std::string& wallpaper_files_id) {
   NOTIMPLEMENTED();
 }
 
 void TestWallpaperController::GetOfflineWallpaperList(
-    ash::mojom::WallpaperController::GetOfflineWallpaperListCallback callback) {
+    GetOfflineWallpaperListCallback callback) {
   NOTIMPLEMENTED();
 }
 
@@ -177,41 +167,41 @@
 }
 
 void TestWallpaperController::AddObserver(
-    ash::mojom::WallpaperObserverAssociatedPtrInfo observer) {
-  ash::mojom::WallpaperObserverAssociatedPtr observer_ptr;
-  observer_ptr.Bind(std::move(observer));
-  test_observers_.AddPtr(std::move(observer_ptr));
+    ash::WallpaperControllerObserver* observer) {
+  observers_.AddObserver(observer);
 }
 
-void TestWallpaperController::GetWallpaperImage(
-    ash::mojom::WallpaperController::GetWallpaperImageCallback callback) {
-  std::move(callback).Run(current_wallpaper);
+void TestWallpaperController::RemoveObserver(
+    ash::WallpaperControllerObserver* observer) {
+  observers_.RemoveObserver(observer);
 }
 
-void TestWallpaperController::GetWallpaperColors(
-    ash::mojom::WallpaperController::GetWallpaperColorsCallback callback) {
+gfx::ImageSkia TestWallpaperController::GetWallpaperImage() {
+  return current_wallpaper;
+}
+
+const std::vector<SkColor>& TestWallpaperController::GetWallpaperColors() {
   NOTIMPLEMENTED();
+  static std::vector<SkColor> kColors;
+  return kColors;
 }
 
-void TestWallpaperController::IsWallpaperBlurred(
-    ash::mojom::WallpaperController::IsWallpaperBlurredCallback callback) {
+bool TestWallpaperController::IsWallpaperBlurred() {
   NOTIMPLEMENTED();
+  return false;
 }
 
-void TestWallpaperController::IsActiveUserWallpaperControlledByPolicy(
-    ash::mojom::WallpaperController::
-        IsActiveUserWallpaperControlledByPolicyCallback callback) {
+bool TestWallpaperController::IsActiveUserWallpaperControlledByPolicy() {
   NOTIMPLEMENTED();
+  return false;
 }
 
-void TestWallpaperController::GetActiveUserWallpaperInfo(
-    ash::mojom::WallpaperController::GetActiveUserWallpaperInfoCallback
-        callback) {
+ash::WallpaperInfo TestWallpaperController::GetActiveUserWallpaperInfo() {
   NOTIMPLEMENTED();
+  return {};
 }
 
-void TestWallpaperController::ShouldShowWallpaperSetting(
-    ash::mojom::WallpaperController::ShouldShowWallpaperSettingCallback
-        callback) {
+bool TestWallpaperController::ShouldShowWallpaperSetting() {
   NOTIMPLEMENTED();
+  return false;
 }
diff --git a/chrome/browser/ui/ash/test_wallpaper_controller.h b/chrome/browser/ui/ash/test_wallpaper_controller.h
index 83b97fe0..7eb6743 100644
--- a/chrome/browser/ui/ash/test_wallpaper_controller.h
+++ b/chrome/browser/ui/ash/test_wallpaper_controller.h
@@ -5,17 +5,16 @@
 #ifndef CHROME_BROWSER_UI_ASH_TEST_WALLPAPER_CONTROLLER_H_
 #define CHROME_BROWSER_UI_ASH_TEST_WALLPAPER_CONTROLLER_H_
 
-#include "ash/public/interfaces/wallpaper.mojom.h"
+#include "ash/public/cpp/wallpaper_controller.h"
 #include "base/macros.h"
-#include "mojo/public/cpp/bindings/binding.h"
-#include "mojo/public/cpp/bindings/interface_ptr_set.h"
+#include "base/observer_list.h"
+#include "ui/gfx/image/image_skia.h"
 
 // Simulates WallpaperController in ash.
-class TestWallpaperController : ash::mojom::WallpaperController {
+class TestWallpaperController : public ash::WallpaperController {
  public:
   TestWallpaperController();
-
-  ~TestWallpaperController() override;
+  ~TestWallpaperController();
 
   // Simulates showing the wallpaper on screen by updating |current_wallpaper|
   // and notifying the observers.
@@ -37,98 +36,76 @@
     return remove_always_on_top_wallpaper_count_;
   }
 
-  // Returns a mojo interface pointer bound to this object.
-  ash::mojom::WallpaperControllerPtr CreateInterfacePtr();
-
-  // ash::mojom::WallpaperController:
-  void Init(ash::mojom::WallpaperControllerClientPtr client,
+  // ash::WallpaperController:
+  void Init(ash::WallpaperControllerClient* client,
             const base::FilePath& user_data_path,
             const base::FilePath& chromeos_wallpapers_path,
             const base::FilePath& chromeos_custom_wallpapers_path,
             const base::FilePath& device_policy_wallpaper_path) override;
-  void SetCustomWallpaper(ash::mojom::WallpaperUserInfoPtr user_info,
+  void SetCustomWallpaper(const ash::WallpaperUserInfo& user_info,
                           const std::string& wallpaper_files_id,
                           const std::string& file_name,
                           ash::WallpaperLayout layout,
                           const gfx::ImageSkia& image,
                           bool preview_mode) override;
   void SetOnlineWallpaperIfExists(
-      ash::mojom::WallpaperUserInfoPtr user_info,
+      const ash::WallpaperUserInfo& user_info,
       const std::string& url,
       ash::WallpaperLayout layout,
       bool preview_mode,
-      ash::mojom::WallpaperController::SetOnlineWallpaperIfExistsCallback
-          callback) override;
+      SetOnlineWallpaperIfExistsCallback callback) override;
   void SetOnlineWallpaperFromData(
-      ash::mojom::WallpaperUserInfoPtr user_info,
+      const ash::WallpaperUserInfo& user_info,
       const std::string& image_data,
       const std::string& url,
       ash::WallpaperLayout layout,
       bool preview_mode,
       SetOnlineWallpaperFromDataCallback callback) override;
-  void SetDefaultWallpaper(ash::mojom::WallpaperUserInfoPtr user_info,
+  void SetDefaultWallpaper(const ash::WallpaperUserInfo& user_info,
                            const std::string& wallpaper_files_id,
                            bool show_wallpaper) override;
   void SetCustomizedDefaultWallpaperPaths(
       const base::FilePath& customized_default_small_path,
       const base::FilePath& customized_default_large_path) override;
-  void SetPolicyWallpaper(ash::mojom::WallpaperUserInfoPtr user_info,
+  void SetPolicyWallpaper(const ash::WallpaperUserInfo& user_info,
                           const std::string& wallpaper_files_id,
                           const std::string& data) override;
   void SetDevicePolicyWallpaperPath(
       const base::FilePath& device_policy_wallpaper_path) override;
-  void SetThirdPartyWallpaper(
-      ash::mojom::WallpaperUserInfoPtr user_info,
-      const std::string& wallpaper_files_id,
-      const std::string& file_name,
-      ash::WallpaperLayout layout,
-      const gfx::ImageSkia& image,
-      ash::mojom::WallpaperController::SetThirdPartyWallpaperCallback callback)
-      override;
+  bool SetThirdPartyWallpaper(const ash::WallpaperUserInfo& user_info,
+                              const std::string& wallpaper_files_id,
+                              const std::string& file_name,
+                              ash::WallpaperLayout layout,
+                              const gfx::ImageSkia& image) override;
   void ConfirmPreviewWallpaper() override;
   void CancelPreviewWallpaper() override;
-  void UpdateCustomWallpaperLayout(ash::mojom::WallpaperUserInfoPtr user_info,
+  void UpdateCustomWallpaperLayout(const ash::WallpaperUserInfo& user_info,
                                    ash::WallpaperLayout layout) override;
-  void ShowUserWallpaper(ash::mojom::WallpaperUserInfoPtr user_info) override;
+  void ShowUserWallpaper(const ash::WallpaperUserInfo& user_info) override;
   void ShowSigninWallpaper() override;
   void ShowOneShotWallpaper(const gfx::ImageSkia& image) override;
   void ShowAlwaysOnTopWallpaper(const base::FilePath& image_path) override;
   void RemoveAlwaysOnTopWallpaper() override;
-  void RemoveUserWallpaper(ash::mojom::WallpaperUserInfoPtr user_info,
+  void RemoveUserWallpaper(const ash::WallpaperUserInfo& user_info,
                            const std::string& wallpaper_files_id) override;
-  void RemovePolicyWallpaper(ash::mojom::WallpaperUserInfoPtr user_info,
+  void RemovePolicyWallpaper(const ash::WallpaperUserInfo& user_info,
                              const std::string& wallpaper_files_id) override;
   void GetOfflineWallpaperList(
-      ash::mojom::WallpaperController::GetOfflineWallpaperListCallback callback)
-      override;
+      GetOfflineWallpaperListCallback callback) override;
   void SetAnimationDuration(base::TimeDelta animation_duration) override;
   void OpenWallpaperPickerIfAllowed() override;
   void MinimizeInactiveWindows(const std::string& user_id_hash) override;
   void RestoreMinimizedWindows(const std::string& user_id_hash) override;
-  void AddObserver(
-      ash::mojom::WallpaperObserverAssociatedPtrInfo observer) override;
-  void GetWallpaperImage(
-      ash::mojom::WallpaperController::GetWallpaperImageCallback callback)
-      override;
-  void GetWallpaperColors(
-      ash::mojom::WallpaperController::GetWallpaperColorsCallback callback)
-      override;
-  void IsWallpaperBlurred(
-      ash::mojom::WallpaperController::IsWallpaperBlurredCallback callback)
-      override;
-  void IsActiveUserWallpaperControlledByPolicy(
-      ash::mojom::WallpaperController::
-          IsActiveUserWallpaperControlledByPolicyCallback callback) override;
-  void GetActiveUserWallpaperInfo(
-      ash::mojom::WallpaperController::GetActiveUserWallpaperInfoCallback
-          callback) override;
-  void ShouldShowWallpaperSetting(
-      ash::mojom::WallpaperController::ShouldShowWallpaperSettingCallback
-          callback) override;
+  void AddObserver(ash::WallpaperControllerObserver* observer) override;
+  void RemoveObserver(ash::WallpaperControllerObserver* observer) override;
+  gfx::ImageSkia GetWallpaperImage() override;
+  const std::vector<SkColor>& GetWallpaperColors() override;
+  bool IsWallpaperBlurred() override;
+  bool IsActiveUserWallpaperControlledByPolicy() override;
+  ash::WallpaperInfo GetActiveUserWallpaperInfo() override;
+  bool ShouldShowWallpaperSetting() override;
 
  private:
-  mojo::Binding<ash::mojom::WallpaperController> binding_;
-
   bool was_client_set_ = false;
   int remove_user_wallpaper_count_ = 0;
   int set_default_wallpaper_count_ = 0;
@@ -136,8 +113,7 @@
   int show_always_on_top_wallpaper_count_ = 0;
   int remove_always_on_top_wallpaper_count_ = 0;
 
-  mojo::AssociatedInterfacePtrSet<ash::mojom::WallpaperObserver>
-      test_observers_;
+  base::ObserverList<ash::WallpaperControllerObserver>::Unchecked observers_;
 
   gfx::ImageSkia current_wallpaper;
 
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client.cc b/chrome/browser/ui/ash/wallpaper_controller_client.cc
index 026caed..fed413b 100644
--- a/chrome/browser/ui/ash/wallpaper_controller_client.cc
+++ b/chrome/browser/ui/ash/wallpaper_controller_client.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/ui/ash/wallpaper_controller_client.h"
 
-#include "ash/public/interfaces/constants.mojom.h"
+#include "ash/public/cpp/wallpaper_user_info.h"
 #include "base/bind.h"
 #include "base/hash/sha1.h"
 #include "base/path_service.h"
@@ -40,27 +40,26 @@
 
 WallpaperControllerClient* g_wallpaper_controller_client_instance = nullptr;
 
-// Creates a mojom::WallpaperUserInfo for the account id. Returns nullptr if
-// user manager cannot find the user.
-ash::mojom::WallpaperUserInfoPtr AccountIdToWallpaperUserInfo(
+// Creates a WallpaperUserInfo for the account id. Returns nullptr if user
+// manager cannot find the user.
+base::Optional<ash::WallpaperUserInfo> AccountIdToWallpaperUserInfo(
     const AccountId& account_id) {
   if (!account_id.is_valid()) {
     // |account_id| may be invalid in tests.
-    return nullptr;
+    return base::nullopt;
   }
   const user_manager::User* user =
       user_manager::UserManager::Get()->FindUser(account_id);
   if (!user)
-    return nullptr;
+    return base::nullopt;
 
-  ash::mojom::WallpaperUserInfoPtr wallpaper_user_info =
-      ash::mojom::WallpaperUserInfo::New();
-  wallpaper_user_info->account_id = account_id;
-  wallpaper_user_info->type = user->GetType();
-  wallpaper_user_info->is_ephemeral =
+  ash::WallpaperUserInfo wallpaper_user_info;
+  wallpaper_user_info.account_id = account_id;
+  wallpaper_user_info.type = user->GetType();
+  wallpaper_user_info.is_ephemeral =
       user_manager::UserManager::Get()->IsUserNonCryptohomeDataEphemeral(
           account_id);
-  wallpaper_user_info->has_gaia_account = user->HasGaiaAccount();
+  wallpaper_user_info.has_gaia_account = user->HasGaiaAccount();
 
   return wallpaper_user_info;
 }
@@ -134,8 +133,7 @@
 
 }  // namespace
 
-WallpaperControllerClient::WallpaperControllerClient()
-    : binding_(this), weak_factory_(this) {
+WallpaperControllerClient::WallpaperControllerClient() : weak_factory_(this) {
   local_state_ = g_browser_process->local_state();
   show_user_names_on_signin_subscription_ =
       chromeos::CrosSettings::Get()->AddSettingsObserver(
@@ -161,16 +159,14 @@
       base::BindRepeating(
           &WallpaperControllerClient::DeviceWallpaperImageFilePathChanged,
           weak_factory_.GetWeakPtr()));
-  content::ServiceManagerConnection::GetForProcess()
-      ->GetConnector()
-      ->BindInterface(ash::mojom::kServiceName, &wallpaper_controller_);
-  BindAndSetClient();
+  wallpaper_controller_ = ash::WallpaperController::Get();
+  InitController();
 }
 
 void WallpaperControllerClient::InitForTesting(
-    ash::mojom::WallpaperControllerPtr controller) {
-  wallpaper_controller_ = std::move(controller);
-  BindAndSetClient();
+    ash::WallpaperController* controller) {
+  wallpaper_controller_ = controller;
+  InitController();
 }
 
 // static
@@ -201,11 +197,10 @@
     ash::WallpaperLayout layout,
     const gfx::ImageSkia& image,
     bool preview_mode) {
-  ash::mojom::WallpaperUserInfoPtr user_info =
-      AccountIdToWallpaperUserInfo(account_id);
+  auto user_info = AccountIdToWallpaperUserInfo(account_id);
   if (!user_info)
     return;
-  wallpaper_controller_->SetCustomWallpaper(std::move(user_info),
+  wallpaper_controller_->SetCustomWallpaper(user_info.value(),
                                             wallpaper_files_id, file_name,
                                             layout, image, preview_mode);
 }
@@ -215,14 +210,12 @@
     const std::string& url,
     ash::WallpaperLayout layout,
     bool preview_mode,
-    ash::mojom::WallpaperController::SetOnlineWallpaperIfExistsCallback
-        callback) {
-  ash::mojom::WallpaperUserInfoPtr user_info =
-      AccountIdToWallpaperUserInfo(account_id);
+    ash::WallpaperController::SetOnlineWallpaperIfExistsCallback callback) {
+  auto user_info = AccountIdToWallpaperUserInfo(account_id);
   if (!user_info)
     return;
   wallpaper_controller_->SetOnlineWallpaperIfExists(
-      std::move(user_info), url, layout, preview_mode, std::move(callback));
+      user_info.value(), url, layout, preview_mode, std::move(callback));
 }
 
 void WallpaperControllerClient::SetOnlineWallpaperFromData(
@@ -231,21 +224,18 @@
     const std::string& url,
     ash::WallpaperLayout layout,
     bool preview_mode,
-    ash::mojom::WallpaperController::SetOnlineWallpaperFromDataCallback
-        callback) {
-  ash::mojom::WallpaperUserInfoPtr user_info =
-      AccountIdToWallpaperUserInfo(account_id);
+    ash::WallpaperController::SetOnlineWallpaperFromDataCallback callback) {
+  auto user_info = AccountIdToWallpaperUserInfo(account_id);
   if (!user_info)
     return;
   wallpaper_controller_->SetOnlineWallpaperFromData(
-      std::move(user_info), image_data, url, layout, preview_mode,
+      user_info.value(), image_data, url, layout, preview_mode,
       std::move(callback));
 }
 
 void WallpaperControllerClient::SetDefaultWallpaper(const AccountId& account_id,
                                                     bool show_wallpaper) {
-  ash::mojom::WallpaperUserInfoPtr user_info =
-      AccountIdToWallpaperUserInfo(account_id);
+  auto user_info = AccountIdToWallpaperUserInfo(account_id);
   if (!user_info)
     return;
 
@@ -261,7 +251,7 @@
   }
 
   wallpaper_controller_->SetDefaultWallpaper(
-      std::move(user_info), GetFilesId(account_id), show_wallpaper);
+      user_info.value(), GetFilesId(account_id), show_wallpaper);
 }
 
 void WallpaperControllerClient::SetCustomizedDefaultWallpaperPaths(
@@ -277,8 +267,7 @@
   if (!data)
     return;
 
-  ash::mojom::WallpaperUserInfoPtr user_info =
-      AccountIdToWallpaperUserInfo(account_id);
+  auto user_info = AccountIdToWallpaperUserInfo(account_id);
   if (!user_info)
     return;
 
@@ -291,24 +280,21 @@
     return;
   }
 
-  wallpaper_controller_->SetPolicyWallpaper(std::move(user_info),
+  wallpaper_controller_->SetPolicyWallpaper(user_info.value(),
                                             GetFilesId(account_id), *data);
 }
 
-void WallpaperControllerClient::SetThirdPartyWallpaper(
+bool WallpaperControllerClient::SetThirdPartyWallpaper(
     const AccountId& account_id,
     const std::string& wallpaper_files_id,
     const std::string& file_name,
     ash::WallpaperLayout layout,
-    const gfx::ImageSkia& image,
-    ash::mojom::WallpaperController::SetThirdPartyWallpaperCallback callback) {
-  ash::mojom::WallpaperUserInfoPtr user_info =
-      AccountIdToWallpaperUserInfo(account_id);
+    const gfx::ImageSkia& image) {
+  auto user_info = AccountIdToWallpaperUserInfo(account_id);
   if (!user_info)
-    return;
-  wallpaper_controller_->SetThirdPartyWallpaper(
-      std::move(user_info), wallpaper_files_id, file_name, layout, image,
-      std::move(callback));
+    return false;
+  return wallpaper_controller_->SetThirdPartyWallpaper(
+      user_info.value(), wallpaper_files_id, file_name, layout, image);
 }
 
 void WallpaperControllerClient::ConfirmPreviewWallpaper() {
@@ -322,20 +308,17 @@
 void WallpaperControllerClient::UpdateCustomWallpaperLayout(
     const AccountId& account_id,
     ash::WallpaperLayout layout) {
-  ash::mojom::WallpaperUserInfoPtr user_info =
-      AccountIdToWallpaperUserInfo(account_id);
+  auto user_info = AccountIdToWallpaperUserInfo(account_id);
   if (!user_info)
     return;
-  wallpaper_controller_->UpdateCustomWallpaperLayout(std::move(user_info),
-                                                     layout);
+  wallpaper_controller_->UpdateCustomWallpaperLayout(user_info.value(), layout);
 }
 
 void WallpaperControllerClient::ShowUserWallpaper(const AccountId& account_id) {
-  ash::mojom::WallpaperUserInfoPtr user_info =
-      AccountIdToWallpaperUserInfo(account_id);
+  auto user_info = AccountIdToWallpaperUserInfo(account_id);
   if (!user_info)
     return;
-  wallpaper_controller_->ShowUserWallpaper(std::move(user_info));
+  wallpaper_controller_->ShowUserWallpaper(user_info.value());
 }
 
 void WallpaperControllerClient::ShowSigninWallpaper() {
@@ -353,8 +336,7 @@
 
 void WallpaperControllerClient::RemoveUserWallpaper(
     const AccountId& account_id) {
-  ash::mojom::WallpaperUserInfoPtr user_info =
-      AccountIdToWallpaperUserInfo(account_id);
+  auto user_info = AccountIdToWallpaperUserInfo(account_id);
   if (!user_info)
     return;
 
@@ -369,14 +351,13 @@
     return;
   }
 
-  wallpaper_controller_->RemoveUserWallpaper(std::move(user_info),
+  wallpaper_controller_->RemoveUserWallpaper(user_info.value(),
                                              GetFilesId(account_id));
 }
 
 void WallpaperControllerClient::RemovePolicyWallpaper(
     const AccountId& account_id) {
-  ash::mojom::WallpaperUserInfoPtr user_info =
-      AccountIdToWallpaperUserInfo(account_id);
+  auto user_info = AccountIdToWallpaperUserInfo(account_id);
   if (!user_info)
     return;
 
@@ -391,12 +372,12 @@
     return;
   }
 
-  wallpaper_controller_->RemovePolicyWallpaper(std::move(user_info),
+  wallpaper_controller_->RemovePolicyWallpaper(user_info.value(),
                                                GetFilesId(account_id));
 }
 
 void WallpaperControllerClient::GetOfflineWallpaperList(
-    ash::mojom::WallpaperController::GetOfflineWallpaperListCallback callback) {
+    ash::WallpaperController::GetOfflineWallpaperListCallback callback) {
   wallpaper_controller_->GetOfflineWallpaperList(std::move(callback));
 }
 
@@ -420,42 +401,37 @@
 }
 
 void WallpaperControllerClient::AddObserver(
-    ash::mojom::WallpaperObserverAssociatedPtrInfo observer) {
-  wallpaper_controller_->AddObserver(std::move(observer));
+    ash::WallpaperControllerObserver* observer) {
+  wallpaper_controller_->AddObserver(observer);
 }
 
-void WallpaperControllerClient::GetWallpaperImage(
-    ash::mojom::WallpaperController::GetWallpaperImageCallback callback) {
-  wallpaper_controller_->GetWallpaperImage(std::move(callback));
+void WallpaperControllerClient::RemoveObserver(
+    ash::WallpaperControllerObserver* observer) {
+  wallpaper_controller_->RemoveObserver(observer);
 }
 
-void WallpaperControllerClient::GetWallpaperColors(
-    ash::mojom::WallpaperController::GetWallpaperColorsCallback callback) {
-  wallpaper_controller_->GetWallpaperColors(std::move(callback));
+gfx::ImageSkia WallpaperControllerClient::GetWallpaperImage() {
+  return wallpaper_controller_->GetWallpaperImage();
 }
 
-void WallpaperControllerClient::IsWallpaperBlurred(
-    ash::mojom::WallpaperController::IsWallpaperBlurredCallback callback) {
-  wallpaper_controller_->IsWallpaperBlurred(std::move(callback));
+const std::vector<SkColor>& WallpaperControllerClient::GetWallpaperColors() {
+  return wallpaper_controller_->GetWallpaperColors();
 }
 
-void WallpaperControllerClient::IsActiveUserWallpaperControlledByPolicy(
-    ash::mojom::WallpaperController::
-        IsActiveUserWallpaperControlledByPolicyCallback callback) {
-  wallpaper_controller_->IsActiveUserWallpaperControlledByPolicy(
-      std::move(callback));
+bool WallpaperControllerClient::IsWallpaperBlurred() {
+  return wallpaper_controller_->IsWallpaperBlurred();
 }
 
-void WallpaperControllerClient::GetActiveUserWallpaperInfo(
-    ash::mojom::WallpaperController::GetActiveUserWallpaperInfoCallback
-        callback) {
-  wallpaper_controller_->GetActiveUserWallpaperInfo(std::move(callback));
+bool WallpaperControllerClient::IsActiveUserWallpaperControlledByPolicy() {
+  return wallpaper_controller_->IsActiveUserWallpaperControlledByPolicy();
 }
 
-void WallpaperControllerClient::ShouldShowWallpaperSetting(
-    ash::mojom::WallpaperController::ShouldShowWallpaperSettingCallback
-        callback) {
-  wallpaper_controller_->ShouldShowWallpaperSetting(std::move(callback));
+ash::WallpaperInfo WallpaperControllerClient::GetActiveUserWallpaperInfo() {
+  return wallpaper_controller_->GetActiveUserWallpaperInfo();
+}
+
+bool WallpaperControllerClient::ShouldShowWallpaperSetting() {
+  return wallpaper_controller_->ShouldShowWallpaperSetting();
 }
 
 void WallpaperControllerClient::DeviceWallpaperImageFilePathChanged() {
@@ -463,14 +439,7 @@
       GetDeviceWallpaperImageFilePath());
 }
 
-void WallpaperControllerClient::FlushForTesting() {
-  wallpaper_controller_.FlushForTesting();
-}
-
-void WallpaperControllerClient::BindAndSetClient() {
-  ash::mojom::WallpaperControllerClientPtr client;
-  binding_.Bind(mojo::MakeRequest(&client));
-
+void WallpaperControllerClient::InitController() {
   // Get the paths of wallpaper directories.
   base::FilePath user_data_path;
   CHECK(base::PathService::Get(chrome::DIR_USER_DATA, &user_data_path));
@@ -484,9 +453,9 @@
   base::FilePath device_policy_wallpaper_path =
       GetDeviceWallpaperImageFilePath();
 
-  wallpaper_controller_->Init(
-      std::move(client), user_data_path, chromeos_wallpapers_path,
-      chromeos_custom_wallpapers_path, device_policy_wallpaper_path);
+  wallpaper_controller_->Init(this, user_data_path, chromeos_wallpapers_path,
+                              chromeos_custom_wallpapers_path,
+                              device_policy_wallpaper_path);
 }
 
 void WallpaperControllerClient::ShowWallpaperOnLoginScreen() {
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client.h b/chrome/browser/ui/ash/wallpaper_controller_client.h
index 5d515b0..11d72c5 100644
--- a/chrome/browser/ui/ash/wallpaper_controller_client.h
+++ b/chrome/browser/ui/ash/wallpaper_controller_client.h
@@ -7,32 +7,33 @@
 
 #include <memory>
 
+#include "ash/public/cpp/wallpaper_controller.h"
+#include "ash/public/cpp/wallpaper_controller_client.h"
 #include "ash/public/cpp/wallpaper_types.h"
-#include "ash/public/interfaces/wallpaper.mojom.h"
 #include "base/macros.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "components/prefs/pref_change_registrar.h"
-#include "mojo/public/cpp/bindings/binding.h"
 
-// Handles method calls sent from ash to chrome. Also sends messages from chrome
-// to ash.
-class WallpaperControllerClient : public ash::mojom::WallpaperControllerClient {
+class AccountId;
+
+// Handles chrome-side wallpaper control alongside the ash-side controller.
+class WallpaperControllerClient : public ash::WallpaperControllerClient {
  public:
   WallpaperControllerClient();
-  ~WallpaperControllerClient() override;
+  virtual ~WallpaperControllerClient();
 
   // Initializes and connects to ash.
   void Init();
 
-  // Tests can provide a mock mojo interface for the ash controller.
-  void InitForTesting(ash::mojom::WallpaperControllerPtr controller);
+  // Tests can provide a mock interface for the ash controller.
+  void InitForTesting(ash::WallpaperController* controller);
 
   static WallpaperControllerClient* Get();
 
   // Returns files identifier for the |account_id|.
   std::string GetFilesId(const AccountId& account_id) const;
 
-  // Wrappers around the ash::mojom::WallpaperController interface.
+  // Wrappers around the ash::WallpaperController interface.
   void SetCustomWallpaper(const AccountId& account_id,
                           const std::string& wallpaper_files_id,
                           const std::string& file_name,
@@ -44,29 +45,25 @@
       const std::string& url,
       ash::WallpaperLayout layout,
       bool preview_mode,
-      ash::mojom::WallpaperController::SetOnlineWallpaperIfExistsCallback
-          callback);
+      ash::WallpaperController::SetOnlineWallpaperIfExistsCallback callback);
   void SetOnlineWallpaperFromData(
       const AccountId& account_id,
       const std::string& image_data,
       const std::string& url,
       ash::WallpaperLayout layout,
       bool preview_mode,
-      ash::mojom::WallpaperController::SetOnlineWallpaperFromDataCallback
-          callback);
+      ash::WallpaperController::SetOnlineWallpaperFromDataCallback callback);
   void SetDefaultWallpaper(const AccountId& account_id, bool show_wallpaper);
   void SetCustomizedDefaultWallpaperPaths(
       const base::FilePath& customized_default_small_path,
       const base::FilePath& customized_default_large_path);
   void SetPolicyWallpaper(const AccountId& account_id,
                           std::unique_ptr<std::string> data);
-  void SetThirdPartyWallpaper(
-      const AccountId& account_id,
-      const std::string& wallpaper_files_id,
-      const std::string& file_name,
-      ash::WallpaperLayout layout,
-      const gfx::ImageSkia& image,
-      ash::mojom::WallpaperController::SetThirdPartyWallpaperCallback callback);
+  bool SetThirdPartyWallpaper(const AccountId& account_id,
+                              const std::string& wallpaper_files_id,
+                              const std::string& file_name,
+                              ash::WallpaperLayout layout,
+                              const gfx::ImageSkia& image);
   void ConfirmPreviewWallpaper();
   void CancelPreviewWallpaper();
   void UpdateCustomWallpaperLayout(const AccountId& account_id,
@@ -78,42 +75,30 @@
   void RemoveUserWallpaper(const AccountId& account_id);
   void RemovePolicyWallpaper(const AccountId& account_id);
   void GetOfflineWallpaperList(
-      ash::mojom::WallpaperController::GetOfflineWallpaperListCallback
-          callback);
+      ash::WallpaperController::GetOfflineWallpaperListCallback callback);
   void SetAnimationDuration(const base::TimeDelta& animation_duration);
   void OpenWallpaperPickerIfAllowed();
   void MinimizeInactiveWindows(const std::string& user_id_hash);
   void RestoreMinimizedWindows(const std::string& user_id_hash);
-  void AddObserver(ash::mojom::WallpaperObserverAssociatedPtrInfo observer);
-  void GetWallpaperImage(
-      ash::mojom::WallpaperController::GetWallpaperImageCallback callback);
-  void GetWallpaperColors(
-      ash::mojom::WallpaperController::GetWallpaperColorsCallback callback);
-  void IsWallpaperBlurred(
-      ash::mojom::WallpaperController::IsWallpaperBlurredCallback callback);
-  void IsActiveUserWallpaperControlledByPolicy(
-      ash::mojom::WallpaperController::
-          IsActiveUserWallpaperControlledByPolicyCallback callback);
-  void GetActiveUserWallpaperInfo(
-      ash::mojom::WallpaperController::GetActiveUserWallpaperInfoCallback
-          callback);
-  void ShouldShowWallpaperSetting(
-      ash::mojom::WallpaperController::ShouldShowWallpaperSettingCallback
-          callback);
-
-  // Flushes the mojo pipe to ash.
-  void FlushForTesting();
+  void AddObserver(ash::WallpaperControllerObserver* observer);
+  void RemoveObserver(ash::WallpaperControllerObserver* observer);
+  gfx::ImageSkia GetWallpaperImage();
+  const std::vector<SkColor>& GetWallpaperColors();
+  bool IsWallpaperBlurred();
+  bool IsActiveUserWallpaperControlledByPolicy();
+  ash::WallpaperInfo GetActiveUserWallpaperInfo();
+  bool ShouldShowWallpaperSetting();
 
  private:
-  // Binds this object to its mojo interface and sets it as the ash client.
-  void BindAndSetClient();
+  // Initialize the controller for this client and some wallpaper directories.
+  void InitController();
 
   // Shows the wallpaper of the first user in |UserManager::GetUsers|, or a
   // default signin wallpaper if there's no user. This ensures the wallpaper is
   // shown right after boot, regardless of when the login screen is available.
   void ShowWallpaperOnLoginScreen();
 
-  // ash::mojom::WallpaperControllerClient:
+  // ash::WallpaperControllerClient:
   void OpenWallpaperPicker() override;
   void OnReadyToSetWallpaper() override;
   void OnFirstWallpaperAnimationFinished() override;
@@ -126,7 +111,7 @@
   base::FilePath GetDeviceWallpaperImageFilePath();
 
   // WallpaperController interface in ash.
-  ash::mojom::WallpaperControllerPtr wallpaper_controller_;
+  ash::WallpaperController* wallpaper_controller_;
 
   PrefService* local_state_;
 
@@ -138,9 +123,6 @@
   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
       show_user_names_on_signin_subscription_;
 
-  // Binds to the client interface.
-  mojo::Binding<ash::mojom::WallpaperControllerClient> binding_;
-
   base::WeakPtrFactory<WallpaperControllerClient> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(WallpaperControllerClient);
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client_unittest.cc b/chrome/browser/ui/ash/wallpaper_controller_client_unittest.cc
index 14bea4c..4cfa016 100644
--- a/chrome/browser/ui/ash/wallpaper_controller_client_unittest.cc
+++ b/chrome/browser/ui/ash/wallpaper_controller_client_unittest.cc
@@ -30,8 +30,7 @@
 TEST_F(WallpaperControllerClientTest, Construction) {
   WallpaperControllerClient client;
   TestWallpaperController controller;
-  client.InitForTesting(controller.CreateInterfacePtr());
-  client.FlushForTesting();
+  client.InitForTesting(&controller);
 
   // Singleton was initialized.
   EXPECT_EQ(&client, WallpaperControllerClient::Get());
diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.cc b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
index f5b9e87f..2f6b64b 100644
--- a/chrome/browser/ui/startup/startup_browser_creator_impl.cc
+++ b/chrome/browser/ui/startup/startup_browser_creator_impl.cc
@@ -26,6 +26,7 @@
 #include "chrome/browser/apps/apps_launch.h"
 #include "chrome/browser/apps/platform_apps/install_chrome_app.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
 #include "chrome/browser/custom_handlers/protocol_handler_registry.h"
 #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
 #include "chrome/browser/defaults.h"
@@ -875,9 +876,12 @@
 #endif
 
 #if BUILDFLAG(ENABLE_PLUGINS)
+    auto* host_content_settings_map =
+        HostContentSettingsMapFactory::GetForProfile(profile_);
     if (FlashDeprecationInfoBarDelegate::ShouldDisplayFlashDeprecation(
-            profile_)) {
-      FlashDeprecationInfoBarDelegate::Create(infobar_service);
+            host_content_settings_map)) {
+      FlashDeprecationInfoBarDelegate::Create(infobar_service,
+                                              host_content_settings_map);
     }
 #endif
   }
diff --git a/chrome/browser/ui/toolbar/app_menu_model.cc b/chrome/browser/ui/toolbar/app_menu_model.cc
index 449f153..0abc4d7 100644
--- a/chrome/browser/ui/toolbar/app_menu_model.cc
+++ b/chrome/browser/ui/toolbar/app_menu_model.cc
@@ -124,7 +124,7 @@
   if (!web_contents)
     return base::nullopt;
   base::string16 app_name =
-      banners::AppBannerManager::GetInstallableAppName(web_contents);
+      banners::AppBannerManager::GetInstallableWebAppName(web_contents);
   if (app_name.empty())
     return base::nullopt;
   return l10n_util::GetStringFUTF16(IDS_INSTALL_TO_OS_LAUNCH_SURFACE, app_name);
diff --git a/chrome/browser/ui/views/certificate_viewer_mac_views.mm b/chrome/browser/ui/views/certificate_viewer_mac_views.mm
index c8183de3..e02800d 100644
--- a/chrome/browser/ui/views/certificate_viewer_mac_views.mm
+++ b/chrome/browser/ui/views/certificate_viewer_mac_views.mm
@@ -10,12 +10,12 @@
 #import "base/mac/scoped_nsobject.h"
 #include "chrome/browser/certificate_viewer.h"
 #include "components/constrained_window/constrained_window_views.h"
+#include "components/remote_cocoa/browser/window.h"
 #include "components/web_modal/web_contents_modal_dialog_manager.h"
 #include "content/public/browser/web_contents.h"
 #include "net/cert/x509_certificate.h"
 #include "net/cert/x509_util_ios_and_mac.h"
 #include "net/cert/x509_util_mac.h"
-#include "ui/base/cocoa/remote_views_window.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/widget/widget_delegate.h"
 
@@ -165,9 +165,9 @@
     // Cocoa should be wrapped in a mojo interface in order to allow
     // instantiating across processes. As a temporary solution, create a
     // transparent in-process window to the front.
-    if (ui::IsWindowUsingRemoteViews(overlayNSWindow)) {
+    if (remote_cocoa::IsWindowRemote(overlayNSWindow)) {
       remote_views_clone_window_ =
-          ui::CreateTransparentRemoteViewsClone(overlayNSWindow);
+          remote_cocoa::CreateInProcessTransparentClone(overlayNSWindow);
       overlayNSWindow = remote_views_clone_window_;
     }
     [certificate_viewer_ showCertificateSheet:overlayNSWindow];
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 4b415ff5..570320c 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -3206,7 +3206,7 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 // BrowserView, banners::AppBannerManager::Observer implementation:
-void BrowserView::OnInstallabilityUpdated() {
+void BrowserView::OnInstallableWebAppStatusUpdated() {
   GetOmniboxPageActionIconContainer()->UpdatePageActionIcon(
       PageActionIconType::kPwaInstall);
 }
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h
index be56992..734d2a152 100644
--- a/chrome/browser/ui/views/frame/browser_view.h
+++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -537,7 +537,7 @@
   void OnImmersiveModeControllerDestroyed() override;
 
   // banners::AppBannerManager::Observer:
-  void OnInstallabilityUpdated() override;
+  void OnInstallableWebAppStatusUpdated() override;
 
   // Creates an accessible tab label for screen readers that includes the tab
   // status for the given tab index. This takes the form of
diff --git a/chrome/browser/ui/views/page_action/pwa_install_view.cc b/chrome/browser/ui/views/page_action/pwa_install_view.cc
index 88beb100..1aae1525 100644
--- a/chrome/browser/ui/views/page_action/pwa_install_view.cc
+++ b/chrome/browser/ui/views/page_action/pwa_install_view.cc
@@ -35,7 +35,7 @@
   if (!manager)
     return false;
 
-  bool is_probably_installable = manager->IsProbablyInstallable();
+  bool is_probably_installable = manager->IsProbablyInstallableWebApp();
   auto* tab_helper =
       web_app::WebAppTabHelperBase::FromWebContents(web_contents);
   bool is_installed = tab_helper && tab_helper->HasAssociatedApp();
@@ -74,5 +74,5 @@
     return base::string16();
   return l10n_util::GetStringFUTF16(
       IDS_OMNIBOX_PWA_INSTALL_ICON_TOOLTIP,
-      banners::AppBannerManager::GetInstallableAppName(web_contents));
+      banners::AppBannerManager::GetInstallableWebAppName(web_contents));
 }
diff --git a/chrome/browser/ui/views/passwords/auto_signin_first_run_dialog_view.cc b/chrome/browser/ui/views/passwords/auto_signin_first_run_dialog_view.cc
index 2669abc..01e9f88 100644
--- a/chrome/browser/ui/views/passwords/auto_signin_first_run_dialog_view.cc
+++ b/chrome/browser/ui/views/passwords/auto_signin_first_run_dialog_view.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/ui/views/chrome_typography.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/constrained_window/constrained_window_views.h"
+#include "components/strings/grit/components_strings.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/views/border.h"
 #include "ui/views/controls/label.h"
@@ -88,7 +89,7 @@
     ui::DialogButton button) const {
   return l10n_util::GetStringUTF16(button == ui::DIALOG_BUTTON_OK
                                        ? IDS_AUTO_SIGNIN_FIRST_RUN_OK
-                                       : IDS_AUTO_SIGNIN_FIRST_RUN_TURN_OFF);
+                                       : IDS_TURN_OFF);
 }
 
 void AutoSigninFirstRunDialogView::InitWindow() {
diff --git a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
index 15254147..4048fdd 100644
--- a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
+++ b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
@@ -564,6 +564,7 @@
   data.network_state = TabNetworkStateForWebContents(contents);
   data.title = tab_ui_helper->GetTitle();
   data.visible_url = contents->GetVisibleURL();
+  data.last_committed_url = contents->GetLastCommittedURL();
   data.crashed_status = contents->GetCrashedStatus();
   data.incognito = contents->GetBrowserContext()->IsOffTheRecord();
   data.pinned = model_->IsTabPinned(model_index);
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc
index 1567afd8..3f491042f 100644
--- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc
+++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc
@@ -478,7 +478,7 @@
   title_label_->SetText(data.title);
 
   base::string16 domain = url_formatter::FormatUrl(
-      data.visible_url,
+      data.last_committed_url,
       url_formatter::kFormatUrlOmitDefaults |
           url_formatter::kFormatUrlOmitHTTPS |
           url_formatter::kFormatUrlOmitTrivialSubdomains |
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view_browsertest.cc b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view_browsertest.cc
index 3514172..2c701e91 100644
--- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view_browsertest.cc
+++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view_browsertest.cc
@@ -203,10 +203,11 @@
 IN_PROC_BROWSER_TEST_F(TabHoverCardBubbleViewBrowserTest, WidgetDataUpdate) {
   TabStrip* tab_strip =
       BrowserView::GetBrowserViewForBrowser(browser())->tabstrip();
-  TabRendererData newTabData = TabRendererData();
-  newTabData.title = base::UTF8ToUTF16("Test Tab 2");
-  newTabData.visible_url = GURL("http://example.com/this/should/not/be/seen");
-  tab_strip->AddTabAt(1, newTabData, false);
+  TabRendererData new_tab_data = TabRendererData();
+  new_tab_data.title = base::UTF8ToUTF16("Test Tab 2");
+  new_tab_data.last_committed_url =
+      GURL("http://example.com/this/should/not/be/seen");
+  tab_strip->AddTabAt(1, new_tab_data, false);
 
   ShowUi("default");
   TabHoverCardBubbleView* hover_card = GetHoverCard(tab_strip);
diff --git a/chrome/browser/ui/views/tabs/tab_renderer_data.cc b/chrome/browser/ui/views/tabs/tab_renderer_data.cc
index ae6ee23d..2e71a69 100644
--- a/chrome/browser/ui/views/tabs/tab_renderer_data.cc
+++ b/chrome/browser/ui/views/tabs/tab_renderer_data.cc
@@ -22,6 +22,7 @@
          thumbnail.BackedBySameObjectAs(other.thumbnail) &&
          network_state == other.network_state && title == other.title &&
          visible_url == other.visible_url &&
+         last_committed_url == other.last_committed_url &&
          crashed_status == other.crashed_status &&
          incognito == other.incognito && show_icon == other.show_icon &&
          pinned == other.pinned && blocked == other.blocked &&
diff --git a/chrome/browser/ui/views/tabs/tab_renderer_data.h b/chrome/browser/ui/views/tabs/tab_renderer_data.h
index 172decf9..2f24856b 100644
--- a/chrome/browser/ui/views/tabs/tab_renderer_data.h
+++ b/chrome/browser/ui/views/tabs/tab_renderer_data.h
@@ -35,6 +35,8 @@
   base::string16 title;
   // This corresponds to WebContents::GetVisibleUrl().
   GURL visible_url;
+  // This corresponds to WebContents::GetLastCommittedUrl().
+  GURL last_committed_url;
   base::TerminationStatus crashed_status =
       base::TERMINATION_STATUS_STILL_RUNNING;
   bool incognito = false;
diff --git a/chrome/browser/ui/webui/chromeos/cellular_setup/cellular_setup_localized_strings_provider.cc b/chrome/browser/ui/webui/chromeos/cellular_setup/cellular_setup_localized_strings_provider.cc
index 3519602a..77976c56 100644
--- a/chrome/browser/ui/webui/chromeos/cellular_setup/cellular_setup_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/chromeos/cellular_setup/cellular_setup_localized_strings_provider.cc
@@ -21,7 +21,11 @@
     {"cancel", IDS_CANCEL},
     {"back", IDS_CELLULAR_SETUP_BACK_LABEL},
     {"finish", IDS_CELLULAR_SETUP_FINISH_LABEL},
-    {"tryAgain", IDS_CELLULAR_SETUP_TRY_AGAIN_LABEL}};
+    {"tryAgain", IDS_CELLULAR_SETUP_TRY_AGAIN_LABEL},
+    {"simDetectPageTitle", IDS_CELLULAR_SETUP_SIM_DETECT_PAGE_TITLE},
+    {"provisioningPageTitle", IDS_CELLULAR_SETUP_PROVISIONING_PAGE_TITLE},
+    {"successPageTitle", IDS_CELLULAR_SETUP_SUCCESS_PAGE_TITLE},
+    {"successPageMessage", IDS_CELLULAR_SETUP_SUCCESS_PAGE_MESSAGE}};
 
 }  //  namespace
 
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 eef88d33..71aabddc 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -233,7 +233,6 @@
       proxy_auth_dialog_reload_times_(kMaxGaiaReloadForProxyAuthDialog),
       gaia_screen_handler_(gaia_screen_handler),
       histogram_helper_(new ErrorScreensHistogramHelper("Signin")),
-      observer_binding_(this),
       weak_factory_(this) {
   DCHECK(network_state_informer_.get());
   DCHECK(error_screen_);
@@ -268,12 +267,12 @@
   tablet_mode_client->AddObserver(this);
   OnTabletModeToggled(tablet_mode_client->tablet_mode_enabled());
 
-  ash::mojom::WallpaperObserverAssociatedPtrInfo ptr_info;
-  observer_binding_.Bind(mojo::MakeRequest(&ptr_info));
-  WallpaperControllerClient::Get()->AddObserver(std::move(ptr_info));
+  WallpaperControllerClient::Get()->AddObserver(this);
 }
 
 SigninScreenHandler::~SigninScreenHandler() {
+  if (auto* wallpaper_controller_client = WallpaperControllerClient::Get())
+    wallpaper_controller_client->RemoveObserver(this);
   TabletModeClient::Get()->RemoveObserver(this);
   OobeUI* oobe_ui = GetOobeUI();
   if (oobe_ui && oobe_ui_observer_added_)
@@ -828,14 +827,12 @@
   }
 }
 
-void SigninScreenHandler::OnWallpaperChanged(uint32_t image_id) {}
-
-void SigninScreenHandler::OnWallpaperColorsChanged(
-    const std::vector<SkColor>& prominent_colors) {
+void SigninScreenHandler::OnWallpaperColorsChanged() {
   // Updates the color of the scrollable container on account picker screen,
   // based on wallpaper color extraction results.
+  auto colors = WallpaperControllerClient::Get()->GetWallpaperColors();
   SkColor dark_muted_color =
-      prominent_colors[static_cast<int>(ash::ColorProfileType::DARK_MUTED)];
+      colors[static_cast<int>(ash::ColorProfileType::DARK_MUTED)];
   if (dark_muted_color == ash::kInvalidWallpaperColor)
     dark_muted_color = ash::login_constants::kDefaultBaseColor;
 
@@ -851,9 +848,10 @@
          color_utils::SkColorToRgbaString(scroll_color));
 }
 
-void SigninScreenHandler::OnWallpaperBlurChanged(bool blurred) {
-  CallJS("login.AccountPickerScreen.togglePodBackground",
-         !blurred /*show_pod_background=*/);
+void SigninScreenHandler::OnWallpaperBlurChanged() {
+  const bool show_pod_background =
+      !WallpaperControllerClient::Get()->IsWallpaperBlurred();
+  CallJS("login.AccountPickerScreen.togglePodBackground", show_pod_background);
 }
 
 void SigninScreenHandler::ClearAndEnablePassword() {
@@ -1209,12 +1207,8 @@
 
   // The wallpaper may have been set before the instance is initialized, so make
   // sure the colors and blur state are updated.
-  WallpaperControllerClient::Get()->GetWallpaperColors(
-      base::BindOnce(&SigninScreenHandler::OnWallpaperColorsChanged,
-                     weak_factory_.GetWeakPtr()));
-  WallpaperControllerClient::Get()->IsWallpaperBlurred(
-      base::BindOnce(&SigninScreenHandler::OnWallpaperBlurChanged,
-                     weak_factory_.GetWeakPtr()));
+  OnWallpaperColorsChanged();
+  OnWallpaperBlurChanged();
 
   session_manager::SessionManager* session_manager =
       session_manager::SessionManager::Get();
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
index c2ab54e..48988d3 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
@@ -10,7 +10,7 @@
 #include <set>
 #include <string>
 
-#include "ash/public/interfaces/wallpaper.mojom.h"
+#include "ash/public/cpp/wallpaper_controller_observer.h"
 #include "base/callback.h"
 #include "base/compiler_specific.h"
 #include "base/macros.h"
@@ -32,7 +32,6 @@
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/web_ui.h"
-#include "mojo/public/cpp/bindings/associated_binding.h"
 #include "net/base/net_errors.h"
 #include "ui/base/ime/chromeos/ime_keyboard.h"
 #include "ui/base/ime/chromeos/input_method_manager.h"
@@ -186,7 +185,7 @@
       public input_method::ImeKeyboard::Observer,
       public TabletModeClientObserver,
       public OobeUI::Observer,
-      public ash::mojom::WallpaperObserver {
+      public ash::WallpaperControllerObserver {
  public:
   SigninScreenHandler(
       JSCallsContainer* js_calls_container,
@@ -225,11 +224,9 @@
                               OobeScreenId new_screen) override;
   void OnDestroyingOobeUI() override {}
 
-  // ash::mojom::WallpaperObserver implementation:
-  void OnWallpaperChanged(uint32_t image_id) override;
-  void OnWallpaperColorsChanged(
-      const std::vector<SkColor>& prominent_colors) override;
-  void OnWallpaperBlurChanged(bool blurred) override;
+  // ash::WallpaperControllerObserver implementation:
+  void OnWallpaperColorsChanged() override;
+  void OnWallpaperBlurChanged() override;
 
   void SetFocusPODCallbackForTesting(base::Closure callback);
 
@@ -506,9 +503,6 @@
 
   std::unique_ptr<AccountId> focused_pod_account_id_;
 
-  // The binding this instance uses to implement ash::mojom::WallpaperObserver.
-  mojo::AssociatedBinding<ash::mojom::WallpaperObserver> observer_binding_;
-
   base::WeakPtrFactory<SigninScreenHandler> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(SigninScreenHandler);
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
index 7d42eca7..8f3f07a8 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
@@ -10,6 +10,7 @@
 #include <memory>
 #include <string>
 #include <utility>
+#include <vector>
 
 #include "base/base64.h"
 #include "base/bind.h"
@@ -855,22 +856,13 @@
                                        printer_name));
 }
 
-void PrintPreviewHandler::OnSigninComplete(const std::string& callback_id) {
-  ResolveJavascriptCallback(base::Value(callback_id), base::Value());
-}
-
 void PrintPreviewHandler::HandleSignin(const base::ListValue* args) {
-  std::string callback_id;
   bool add_account = false;
-  CHECK(args->GetString(0, &callback_id));
-  CHECK(!callback_id.empty());
-  CHECK(args->GetBoolean(1, &add_account));
+  CHECK(args->GetBoolean(0, &add_account));
 
   chrome::ScopedTabbedBrowserDisplayer displayer(Profile::FromWebUI(web_ui()));
-  print_dialog_cloud::CreateCloudPrintSigninTab(
-      displayer.browser(), add_account,
-      base::Bind(&PrintPreviewHandler::OnSigninComplete,
-                 weak_factory_.GetWeakPtr(), callback_id));
+  print_dialog_cloud::CreateCloudPrintSigninTab(displayer.browser(),
+                                                add_account);
 }
 
 #if defined(OS_CHROMEOS)
@@ -1001,7 +993,7 @@
     initial_settings.SetBoolKey(kHeaderFooter,
                                 prefs->GetBoolean(prefs::kPrintHeaderFooter));
   }
-  if (prefs->GetBoolean(prefs::kCloudPrintSubmitEnabled) &&
+  if (IsCloudPrintEnabled() &&
       !base::FeatureList::IsEnabled(features::kCloudPrinterHandler)) {
     initial_settings.SetStringKey(
         kCloudPrintURL, GURL(cloud_devices::GetCloudPrintURL()).spec());
@@ -1024,7 +1016,7 @@
   }
 
   GetNumberFormatAndMeasurementSystem(&initial_settings);
-  if (prefs->GetBoolean(prefs::kCloudPrintSubmitEnabled)) {
+  if (IsCloudPrintEnabled()) {
     GetUserAccountList(&initial_settings);
   }
 
@@ -1113,8 +1105,6 @@
   return dialog_controller->GetInitiator(preview_web_contents());
 }
 
-// TODO(crbug.com/932692): Investigate the replacement or removal of
-// this override altogether.
 void PrintPreviewHandler::OnAccountsInCookieUpdated(
     const identity::AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
     const GoogleServiceAuthError& error) {
@@ -1330,22 +1320,28 @@
 
 void PrintPreviewHandler::RegisterForGaiaCookieChanges() {
   DCHECK(!identity_manager_);
+  cloud_print_enabled_ =
+      GetPrefs()->GetBoolean(prefs::kCloudPrintSubmitEnabled);
+
+  if (!cloud_print_enabled_)
+    return;
+
   Profile* profile = Profile::FromWebUI(web_ui());
   identity_manager_ = IdentityManagerFactory::GetForProfile(profile);
-  if (AccountConsistencyModeManager::IsMirrorEnabledForProfile(profile)) {
-    identity_manager_->AddObserver(this);
-  }
+  identity_manager_->AddObserver(this);
 }
 
 void PrintPreviewHandler::UnregisterForGaiaCookieChanges() {
   if (!identity_manager_)
     return;
 
-  Profile* profile = Profile::FromWebUI(web_ui());
-  if (AccountConsistencyModeManager::IsMirrorEnabledForProfile(profile)) {
-    identity_manager_->RemoveObserver(this);
-  }
+  identity_manager_->RemoveObserver(this);
   identity_manager_ = nullptr;
+  cloud_print_enabled_ = false;
+}
+
+bool PrintPreviewHandler::IsCloudPrintEnabled() {
+  return cloud_print_enabled_;
 }
 
 void PrintPreviewHandler::BadMessageReceived() {
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.h b/chrome/browser/ui/webui/print_preview/print_preview_handler.h
index bd85f40..47856437f 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler.h
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.h
@@ -124,6 +124,7 @@
  protected:
   // Protected so unit tests can override.
   virtual PrinterHandler* GetPrinterHandler(PrinterType printer_type);
+  virtual bool IsCloudPrintEnabled();
 
   // Shuts down the initiator renderer. Called when a bad IPC message is
   // received.
@@ -220,11 +221,8 @@
   void HandleShowSystemDialog(const base::ListValue* args);
 #endif
 
-  // Callback for the signin dialog to call once signin is complete.
-  void OnSigninComplete(const std::string& callback_id);
-
-  // Brings up a dialog to allow the user to sign into cloud print.
-  // |args| is unused.
+  // Opens a new tab to allow the user to sign into cloud print. |args| holds
+  // a boolean indicating whether the user is adding an account.
   void HandleSignin(const base::ListValue* args);
 
 #if defined(OS_CHROMEOS)
@@ -322,6 +320,9 @@
   // Whether we have already logged the number of printers this session.
   bool has_logged_printers_count_;
 
+  // Whether Google Cloud Print is enabled for the active profile.
+  bool cloud_print_enabled_ = false;
+
   // The settings used for the most recent preview request.
   base::Value last_preview_settings_;
 
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc
index e065c38..efbbb97 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc
@@ -209,6 +209,8 @@
     return test_printer_handler_.get();
   }
 
+  bool IsCloudPrintEnabled() override { return true; }
+
   void RegisterForGaiaCookieChanges() override {}
   void UnregisterForGaiaCookieChanges() override {}
 
diff --git a/chrome/browser/ui/webui/settings/appearance_handler.cc b/chrome/browser/ui/webui/settings/appearance_handler.cc
index ae92d56..435767b8b 100644
--- a/chrome/browser/ui/webui/settings/appearance_handler.cc
+++ b/chrome/browser/ui/webui/settings/appearance_handler.cc
@@ -71,17 +71,16 @@
 #if defined(OS_CHROMEOS)
 void AppearanceHandler::IsWallpaperSettingVisible(const base::ListValue* args) {
   CHECK_EQ(args->GetSize(), 1U);
-  WallpaperControllerClient::Get()->ShouldShowWallpaperSetting(
-      base::Bind(&AppearanceHandler::ResolveCallback,
-                 weak_ptr_factory_.GetWeakPtr(), args->GetList()[0].Clone()));
+  bool result = WallpaperControllerClient::Get()->ShouldShowWallpaperSetting();
+  ResolveCallback(args->GetList()[0], result);
 }
 
 void AppearanceHandler::IsWallpaperPolicyControlled(
     const base::ListValue* args) {
   CHECK_EQ(args->GetSize(), 1U);
-  WallpaperControllerClient::Get()->IsActiveUserWallpaperControlledByPolicy(
-      base::Bind(&AppearanceHandler::ResolveCallback,
-                 weak_ptr_factory_.GetWeakPtr(), args->GetList()[0].Clone()));
+  bool result = WallpaperControllerClient::Get()
+                    ->IsActiveUserWallpaperControlledByPolicy();
+  ResolveCallback(args->GetList()[0], result);
 }
 
 void AppearanceHandler::HandleOpenWallpaperManager(
diff --git a/chrome/browser/vr/metrics/session_metrics_helper.h b/chrome/browser/vr/metrics/session_metrics_helper.h
index 009f09b..fdf4753 100644
--- a/chrome/browser/vr/metrics/session_metrics_helper.h
+++ b/chrome/browser/vr/metrics/session_metrics_helper.h
@@ -30,8 +30,8 @@
   // The user triggered a presentation request on a page, probably by clicking
   // an enter VR button.
   kPresentationRequest = 2,
-  // The user launched a deep linked app, probably from Daydream home.
-  kDeepLinkedApp = 3,
+  // OBSOLETE: The user launched a deep linked app, probably from Daydream Home.
+  // kDeepLinkedApp = 3,
   // Chrome VR was started by an intent from another app. Most likely the user
   // clicked the icon in Daydream home.
   kIntentLaunch = 4,
@@ -55,9 +55,9 @@
   // The user activated a headset on a page that listens for headset activations
   // and requests presentation.
   kHeadsetActivation = 3,
-  // The user opened a deep linked app, probably from the Daydream homescreen.
-  kDeepLinkedApp = 4,
-  kMaxValue = kDeepLinkedApp,
+  // OBSOLETE: The user launched a deep linked app, probably from Daydream Home.
+  // kDeepLinkedApp = 4,
+  kMaxValue = 4,
 };
 
 // SessionTimer will monitor the time between calls to StartSession and
diff --git a/chrome/chrome_repack_locales.gni b/chrome/chrome_repack_locales.gni
index ba27920..9be56c6 100644
--- a/chrome/chrome_repack_locales.gni
+++ b/chrome/chrome_repack_locales.gni
@@ -31,6 +31,7 @@
       "${root_gen_dir}/content/app/strings/content_strings_",
       "${root_gen_dir}/device/bluetooth/strings/bluetooth_strings_",
       "${root_gen_dir}/device/fido/strings/fido_strings_",
+      "${root_gen_dir}/services/strings/services_strings_",
       "${root_gen_dir}/third_party/libaddressinput/address_input_strings_",
       "${root_gen_dir}/ui/strings/app_locale_settings_",
       "${root_gen_dir}/ui/strings/ui_strings_",
@@ -47,6 +48,7 @@
       "//content/app/strings",
       "//device/bluetooth/strings",
       "//device/fido/strings",
+      "//services/strings",
       "//third_party/libaddressinput:strings",
       "//ui/strings:app_locale_settings",
       "//ui/strings:ui_strings",
diff --git a/chrome/services/cups_proxy/BUILD.gn b/chrome/services/cups_proxy/BUILD.gn
index eb02677..898f6d31 100644
--- a/chrome/services/cups_proxy/BUILD.gn
+++ b/chrome/services/cups_proxy/BUILD.gn
@@ -12,6 +12,8 @@
   sources = [
     "cups_proxy_service.cpp",
     "cups_proxy_service.h",
+    "cups_proxy_service_delegate.cc",
+    "cups_proxy_service_delegate.h",
   ]
 
   deps = [
@@ -32,3 +34,15 @@
     "//printing",
   ]
 }
+
+static_library("test_support") {
+  testonly = true
+  sources = [
+    "fake_cups_proxy_service_delegate.cc",
+    "fake_cups_proxy_service_delegate.h",
+  ]
+
+  public_deps = [
+    ":cups_proxy",
+  ]
+}
diff --git a/chrome/services/cups_proxy/DEPS b/chrome/services/cups_proxy/DEPS
new file mode 100644
index 0000000..4694dc2
--- /dev/null
+++ b/chrome/services/cups_proxy/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+chromeos/printing",
+]
diff --git a/chrome/services/cups_proxy/cups_proxy_service_delegate.cc b/chrome/services/cups_proxy/cups_proxy_service_delegate.cc
new file mode 100644
index 0000000..56ae3319
--- /dev/null
+++ b/chrome/services/cups_proxy/cups_proxy_service_delegate.cc
@@ -0,0 +1,23 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/services/cups_proxy/cups_proxy_service_delegate.h"
+
+#include <memory>
+#include <string>
+
+#include "base/memory/weak_ptr.h"
+
+namespace chromeos {
+namespace printing {
+
+CupsProxyServiceDelegate::CupsProxyServiceDelegate() : weak_factory_(this) {}
+CupsProxyServiceDelegate::~CupsProxyServiceDelegate() = default;
+
+base::WeakPtr<CupsProxyServiceDelegate> CupsProxyServiceDelegate::GetWeakPtr() {
+  return weak_factory_.GetWeakPtr();
+}
+
+}  // namespace printing
+}  // namespace chromeos
diff --git a/chrome/services/cups_proxy/cups_proxy_service_delegate.h b/chrome/services/cups_proxy/cups_proxy_service_delegate.h
new file mode 100644
index 0000000..0db3263
--- /dev/null
+++ b/chrome/services/cups_proxy/cups_proxy_service_delegate.h
@@ -0,0 +1,49 @@
+// Copyright 2019 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.
+
+#ifndef CHROME_SERVICES_CUPS_PROXY_CUPS_PROXY_SERVICE_DELEGATE_H_
+#define CHROME_SERVICES_CUPS_PROXY_CUPS_PROXY_SERVICE_DELEGATE_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
+#include "chromeos/printing/printer_configuration.h"
+
+namespace chromeos {
+namespace printing {
+
+using PrinterSetupCallback = base::OnceCallback<void(bool)>;
+
+// This delegate grants the CupsProxyService access to the Chrome printing
+// stack. This class can be created anywhere but must be accessed from a
+// sequenced context.
+class CupsProxyServiceDelegate {
+ public:
+  CupsProxyServiceDelegate();
+  virtual ~CupsProxyServiceDelegate();
+
+  // Exposing |weak_factory_|.GetWeakPtr method. Needed to share delegate with
+  // CupsProxyService internal managers.
+  base::WeakPtr<CupsProxyServiceDelegate> GetWeakPtr();
+
+  virtual std::vector<chromeos::Printer> GetPrinters() = 0;
+  virtual base::Optional<chromeos::Printer> GetPrinter(
+      const std::string& id) = 0;
+  virtual bool IsPrinterInstalled(const Printer& printer) = 0;
+
+  // |cb| will be run on this delegate's sequenced context.
+  virtual void SetupPrinter(const Printer& printer,
+                            PrinterSetupCallback cb) = 0;
+
+ private:
+  base::WeakPtrFactory<CupsProxyServiceDelegate> weak_factory_;
+};
+
+}  // namespace printing
+}  // namespace chromeos
+
+#endif  // CHROME_SERVICES_CUPS_PROXY_CUPS_PROXY_SERVICE_DELEGATE_H_
diff --git a/chrome/services/cups_proxy/fake_cups_proxy_service_delegate.cc b/chrome/services/cups_proxy/fake_cups_proxy_service_delegate.cc
new file mode 100644
index 0000000..7685271
--- /dev/null
+++ b/chrome/services/cups_proxy/fake_cups_proxy_service_delegate.cc
@@ -0,0 +1,27 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/services/cups_proxy/fake_cups_proxy_service_delegate.h"
+
+namespace chromeos {
+namespace printing {
+
+std::vector<chromeos::Printer> FakeCupsProxyServiceDelegate::GetPrinters() {
+  return {};
+}
+
+base::Optional<chromeos::Printer> FakeCupsProxyServiceDelegate::GetPrinter(
+    const std::string& id) {
+  return base::nullopt;
+}
+
+bool FakeCupsProxyServiceDelegate::IsPrinterInstalled(const Printer& printer) {
+  return false;
+}
+
+void FakeCupsProxyServiceDelegate::SetupPrinter(const Printer& printer,
+                                                PrinterSetupCallback cb) {}
+
+}  // namespace printing
+}  // namespace chromeos
diff --git a/chrome/services/cups_proxy/fake_cups_proxy_service_delegate.h b/chrome/services/cups_proxy/fake_cups_proxy_service_delegate.h
new file mode 100644
index 0000000..c6a2085
--- /dev/null
+++ b/chrome/services/cups_proxy/fake_cups_proxy_service_delegate.h
@@ -0,0 +1,34 @@
+// Copyright 2019 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.
+
+#ifndef CHROME_SERVICES_CUPS_PROXY_FAKE_CUPS_PROXY_SERVICE_DELEGATE_H_
+#define CHROME_SERVICES_CUPS_PROXY_FAKE_CUPS_PROXY_SERVICE_DELEGATE_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "chrome/services/cups_proxy/cups_proxy_service_delegate.h"
+#include "chromeos/printing/printer_configuration.h"
+
+namespace chromeos {
+namespace printing {
+
+// Fake implementation for use in unit_tests.
+class FakeCupsProxyServiceDelegate : public CupsProxyServiceDelegate {
+ public:
+  FakeCupsProxyServiceDelegate() = default;
+  ~FakeCupsProxyServiceDelegate() override = default;
+
+  // CupsProxyServiceDelegate overrides.
+  std::vector<chromeos::Printer> GetPrinters() override;
+  base::Optional<chromeos::Printer> GetPrinter(const std::string& id) override;
+  bool IsPrinterInstalled(const Printer& printer) override;
+  void SetupPrinter(const Printer& printer, PrinterSetupCallback cb) override;
+};
+
+}  // namespace printing
+}  // namespace chromeos
+
+#endif  // CHROME_SERVICES_CUPS_PROXY_FAKE_CUPS_PROXY_SERVICE_DELEGATE_H_
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 0cdeafd..ef83da0 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -488,6 +488,7 @@
       "//ppapi/buildflags",
       "//printing/buildflags",
       "//rlz/buildflags",
+      "//services/strings",
       "//third_party/blink/public:buildflags",
     ]
 
diff --git a/chrome/test/base/chrome_test_launcher.cc b/chrome/test/base/chrome_test_launcher.cc
index e143f3c..0d82f05 100644
--- a/chrome/test/base/chrome_test_launcher.cc
+++ b/chrome/test/base/chrome_test_launcher.cc
@@ -71,6 +71,10 @@
   ChromeTestSuite test_suite(argc, argv);
   // Browser tests are expected not to tear-down various globals.
   test_suite.DisableCheckForLeakedGlobals();
+#if defined(OS_ANDROID)
+  // Android browser tests run child processes as threads instead.
+  content::ContentTestSuiteBase::RegisterInProcessThreads();
+#endif
   return test_suite.Run();
 }
 
diff --git a/chrome/test/base/js2gtest.js b/chrome/test/base/js2gtest.js
index b3d74e66..aafa58a4 100644
--- a/chrome/test/base/js2gtest.js
+++ b/chrome/test/base/js2gtest.js
@@ -24,17 +24,21 @@
   quit(-1);
 }
 
-/**
- * Full path to the test input file, relative to the current working directory.
- * @type {string}
- */
-var fullTestFilePath = arguments[1];
+[
+  _,
+  // Full path to the test input file, relative to the current working
+  // directory.
+  fullTestFilePath,
+  // Path to source-root, relative to the current working directory.
+  srcRootPath,
+  // Path to Closure library style deps.js file.
+  depsFile,
+  // Path to C++ file generation is outputting to.
+  outputFile,
+  // Type of this test. One of 'extension', 'unit', 'webui', 'mojo_lite_webui'.
+  testType
+] = arguments;
 
-/**
- * Path to source-root, relative to the current working directory.
- * @type {string}
- */
-var srcRootPath = arguments[2];
 
 if (!fullTestFilePath.startsWith(srcRootPath)) {
   print('Test file must be a descendant of source root directory');
@@ -47,27 +51,9 @@
  */
 var testFile = fullTestFilePath.substr(srcRootPath.length);
 
-/**
- * Path to Closure library style deps.js file.
- * @type {string?}
- */
-var depsFile = arguments[3];
+const TEST_TYPES = new Set(['extension', 'unit', 'webui', 'mojo_lite_webui']);
 
-/**
- * Path to C++ file generation is outputting to.
- * @type {string}
- */
-var outputFile = arguments[4];
-
-/**
- * Type of this test.
- * @type {string} ('extension' | 'unit' | 'webui' | 'mojo_lite_webui')
- */
-var testType = arguments[5];
-if (testType != 'extension' &&
-    testType != 'unit' &&
-    testType != 'webui' &&
-    testType != 'mojo_lite_webui') {
+if (!TEST_TYPES.has(testType)) {
   print('Invalid test type: ' + testType);
   quit(-1);
 }
@@ -81,9 +67,9 @@
 /**
  * Keeps track of whether a typedef has been generated for each test
  * fixture.
- * @type {Object<string>}
+ * @type {!Map<string, string>}
  */
-var typedeffedCppFixtures = {};
+var typedeffedCppFixtures = new Map();
 
 /**
  * Maintains a list of file paths (relative to source-root directory) to add
@@ -110,12 +96,12 @@
  * Helpful hint pointing back to the source js.
  * @type {string}
  */
-var argHint = '// ' + this['arguments'].join(' ');
+var argHint = '// ' + arguments.join(' ');
 
 /**
  * @type {Array<string>}
  */
-var pendingOutput = '';
+var pendingOutput = [];
 
 /**
  * Adds a string followed by a newline to the pending output.
@@ -126,16 +112,7 @@
   opt_string = opt_string || '';
   if (opt_string[0] == '\n')
     opt_string = opt_string.substring(1);
-    pendingOutput += opt_string;
-  pendingOutput += '\n';
-}
-
-/**
- * Returns number of lines in pending output.
- * @returns {number}
- */
-function countOutputLines() {
-  return pendingOutput.split('\n').length;
+  pendingOutput.push(opt_string);
 }
 
 /**
@@ -415,7 +392,7 @@
       [testFile]);
   var testFLine = getTestDeclarationLineNumber();
 
-  if (typedefCppFixture && !(testFixture in typedeffedCppFixtures)) {
+  if (typedefCppFixture && !typedeffedCppFixtures.has(testFixture)) {
     var switches = this[testFixture].prototype.commandLineSwitches;
     var hasSwitches = switches && switches.length;
     var featureList = this[testFixture].prototype.featureList;
@@ -520,14 +497,14 @@
 };
 `);
     }
-    typedeffedCppFixtures[testFixture] = typedefCppFixture;
+    typedeffedCppFixtures.set(testFixture, typedefCppFixture);
   }
 
   if (opt_preamble) {
     GEN(opt_preamble);
   }
 
-  var outputLine = countOutputLines() + 3;
+  var outputLine = pendingOutput.length + 3;
   output(`
 #line ${testFLine} "${testFile}"
 ${testF}(${testFixture}, ${testFunction}) {
@@ -588,4 +565,4 @@
 pathStack.push(testFile);
 eval(js);
 pathStack.pop();
-print(pendingOutput);
+print(pendingOutput.join('\n'));
diff --git a/chrome/test/base/perf/performance_test.cc b/chrome/test/base/perf/performance_test.cc
index bacb39d..8b7a76d 100644
--- a/chrome/test/base/perf/performance_test.cc
+++ b/chrome/test/base/perf/performance_test.cc
@@ -16,12 +16,13 @@
 #include "ui/gl/gl_switches.h"
 
 #if defined(OS_CHROMEOS)
+#include "ash/public/cpp/wallpaper_controller_observer.h"
 #include "ash/public/cpp/wallpaper_types.h"
 #include "chrome/browser/ui/ash/wallpaper_controller_client.h"
 #include "components/user_manager/user_names.h"
-#include "mojo/public/cpp/bindings/associated_binding.h"
 #include "ui/display/display.h"
 #include "ui/display/screen.h"
+#include "ui/gfx/image/image_skia.h"
 #endif  // OS_CHROMEOS
 
 static const char kTraceDir[] = "trace-dir";
@@ -30,31 +31,23 @@
 
 #if defined(OS_CHROMEOS)
 // Watches if the wallpaper has been changed and runs a passed callback if so.
-class TestWallpaperObserver : public ash::mojom::WallpaperObserver {
+class TestWallpaperObserver : public ash::WallpaperControllerObserver {
  public:
   explicit TestWallpaperObserver(base::OnceClosure closure)
-      : closure_(std::move(closure)), observer_binding_(this) {
-    ash::mojom::WallpaperObserverAssociatedPtrInfo ptr_info;
-    observer_binding_.Bind(mojo::MakeRequest(&ptr_info));
-    WallpaperControllerClient::Get()->AddObserver(std::move(ptr_info));
+      : closure_(std::move(closure)) {
+    WallpaperControllerClient::Get()->AddObserver(this);
   }
 
-  ~TestWallpaperObserver() override = default;
-
-  // ash::mojom::WallpaperObserver:
-  void OnWallpaperChanged(uint32_t image_id) override {
-    std::move(closure_).Run();
+  ~TestWallpaperObserver() override {
+    WallpaperControllerClient::Get()->RemoveObserver(this);
   }
-  void OnWallpaperColorsChanged(
-      const std::vector<uint32_t>& prominent_colors) override {}
-  void OnWallpaperBlurChanged(bool blurred) override {}
+
+  // ash::WallpaperControllerObserver:
+  void OnWallpaperChanged() override { std::move(closure_).Run(); }
 
  private:
   base::OnceClosure closure_;
 
-  // The binding this instance uses to implement ash::mojom::WallpaperObserver.
-  mojo::AssociatedBinding<ash::mojom::WallpaperObserver> observer_binding_;
-
   DISALLOW_COPY_AND_ASSIGN(TestWallpaperObserver);
 };
 
diff --git a/chrome/test/data/media/picture-in-picture/pixel_expected_pause_control.png b/chrome/test/data/media/picture-in-picture/pixel_expected_pause_control.png
new file mode 100644
index 0000000..abb13a8
--- /dev/null
+++ b/chrome/test/data/media/picture-in-picture/pixel_expected_pause_control.png
Binary files differ
diff --git a/chrome/test/data/media/picture-in-picture/pixel_expected_pause_control_crop.png b/chrome/test/data/media/picture-in-picture/pixel_expected_pause_control_crop.png
new file mode 100644
index 0000000..877f104
--- /dev/null
+++ b/chrome/test/data/media/picture-in-picture/pixel_expected_pause_control_crop.png
Binary files differ
diff --git a/chrome/test/data/media/picture-in-picture/pixel_expected_play_control.png b/chrome/test/data/media/picture-in-picture/pixel_expected_play_control.png
new file mode 100644
index 0000000..c6e9b757b
--- /dev/null
+++ b/chrome/test/data/media/picture-in-picture/pixel_expected_play_control.png
Binary files differ
diff --git a/chrome/test/data/media/picture-in-picture/pixel_expected_play_control_crop.png b/chrome/test/data/media/picture-in-picture/pixel_expected_play_control_crop.png
new file mode 100644
index 0000000..a055df07
--- /dev/null
+++ b/chrome/test/data/media/picture-in-picture/pixel_expected_play_control_crop.png
Binary files differ
diff --git a/chrome/test/data/media/picture-in-picture/pixel_expected_video_play.png b/chrome/test/data/media/picture-in-picture/pixel_expected_video_play.png
new file mode 100644
index 0000000..9bfa75d3
--- /dev/null
+++ b/chrome/test/data/media/picture-in-picture/pixel_expected_video_play.png
Binary files differ
diff --git a/chrome/test/data/media/picture-in-picture/pixel_test.html b/chrome/test/data/media/picture-in-picture/pixel_test.html
index 49f3926..8f6e481 100644
--- a/chrome/test/data/media/picture-in-picture/pixel_test.html
+++ b/chrome/test/data/media/picture-in-picture/pixel_test.html
@@ -26,5 +26,16 @@
       window.domAutomationController.send(false);
     });
   }
+
+  function changeVideoSrc() {
+    if (video.srcObject) {
+      video.srcObject.getTracks().forEach(track => track.stop());
+      video.srcObject = null;
+    }
+    video.src = 'pixel_test_video.webm';
+    video.play()
+    .then(_ => { window.domAutomationController.send(true); })
+    .catch(e => { window.domAutomationController.send(false); });
+  }
 </script>
 </html>
diff --git a/chrome/test/data/webui/bookmarks/folder_node_test.js b/chrome/test/data/webui/bookmarks/folder_node_test.js
index e87ab0a..a2f571a 100644
--- a/chrome/test/data/webui/bookmarks/folder_node_test.js
+++ b/chrome/test/data/webui/bookmarks/folder_node_test.js
@@ -46,12 +46,12 @@
         firstGen[0].$['descendants'].querySelectorAll('bookmarks-folder-node');
 
     // Select nested folder.
-    MockInteractions.tap(secondGen[0].$['folder-label']);
+    MockInteractions.tap(secondGen[0].$['container']);
     assertEquals('select-folder', store.lastAction.name);
     assertEquals(secondGen[0].itemId, store.lastAction.id);
 
     // Select folder in a separate subtree.
-    MockInteractions.tap(rootFolders[1].$['folder-label']);
+    MockInteractions.tap(rootFolders[1].$['container']);
     assertEquals('select-folder', store.lastAction.name);
     assertEquals(rootFolders[1].itemId, store.lastAction.id);
 
@@ -60,7 +60,7 @@
     store.notifyObservers();
     store.resetLastAction();
 
-    MockInteractions.tap(rootFolders[1].$['folder-label']);
+    MockInteractions.tap(rootFolders[1].$['container']);
     assertEquals(null, store.lastAction);
   });
 
diff --git a/chrome/test/data/webui/print_preview/native_layer_stub.js b/chrome/test/data/webui/print_preview/native_layer_stub.js
index 083f6ff1..c3d760a3 100644
--- a/chrome/test/data/webui/print_preview/native_layer_stub.js
+++ b/chrome/test/data/webui/print_preview/native_layer_stub.js
@@ -198,7 +198,7 @@
     /** @override */
     signIn(addAccount) {
       this.methodCalled('signIn', addAccount);
-      return Promise.resolve();
+      cr.webUIListenerCallback('reload-printer-list');
     }
 
     /**
diff --git a/chromeos/services/device_sync/BUILD.gn b/chromeos/services/device_sync/BUILD.gn
index 22086aa..dc2a9de 100644
--- a/chromeos/services/device_sync/BUILD.gn
+++ b/chromeos/services/device_sync/BUILD.gn
@@ -23,6 +23,8 @@
     "cryptauth_device_registry.h",
     "cryptauth_device_registry_impl.cc",
     "cryptauth_device_registry_impl.h",
+    "cryptauth_device_sync_result.cc",
+    "cryptauth_device_sync_result.h",
     "cryptauth_enroller.h",
     "cryptauth_enroller_factory_impl.cc",
     "cryptauth_enroller_factory_impl.h",
diff --git a/chromeos/services/device_sync/cryptauth_device_sync_result.cc b/chromeos/services/device_sync/cryptauth_device_sync_result.cc
new file mode 100644
index 0000000..0ceca42a
--- /dev/null
+++ b/chromeos/services/device_sync/cryptauth_device_sync_result.cc
@@ -0,0 +1,58 @@
+// Copyright 2019 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 "chromeos/services/device_sync/cryptauth_device_sync_result.h"
+
+namespace chromeos {
+
+namespace device_sync {
+
+CryptAuthDeviceSyncResult::CryptAuthDeviceSyncResult(
+    ResultCode result_code,
+    const base::Optional<cryptauthv2::ClientDirective>& client_directive)
+    : result_code_(result_code), client_directive_(client_directive) {}
+
+CryptAuthDeviceSyncResult::CryptAuthDeviceSyncResult(
+    const CryptAuthDeviceSyncResult& other) = default;
+
+CryptAuthDeviceSyncResult::~CryptAuthDeviceSyncResult() = default;
+
+bool CryptAuthDeviceSyncResult::IsSuccess() const {
+  return result_code_ == ResultCode::kSuccess;
+}
+
+bool CryptAuthDeviceSyncResult::operator==(
+    const CryptAuthDeviceSyncResult& other) const {
+  return result_code_ == other.result_code_ &&
+         client_directive_.has_value() == other.client_directive_.has_value() &&
+         (!client_directive_ ||
+          client_directive_->SerializeAsString() ==
+              other.client_directive_->SerializeAsString());
+}
+
+bool CryptAuthDeviceSyncResult::operator!=(
+    const CryptAuthDeviceSyncResult& other) const {
+  return !(*this == other);
+}
+
+std::ostream& operator<<(
+    std::ostream& stream,
+    const CryptAuthDeviceSyncResult::ResultCode result_code) {
+  using ResultCode = CryptAuthDeviceSyncResult::ResultCode;
+
+  switch (result_code) {
+    case ResultCode::kSuccess:
+      stream << "[Success]";
+      break;
+    case ResultCode::kError:
+      stream << "[Error]";
+      break;
+  }
+
+  return stream;
+}
+
+}  // namespace device_sync
+
+}  // namespace chromeos
diff --git a/chromeos/services/device_sync/cryptauth_device_sync_result.h b/chromeos/services/device_sync/cryptauth_device_sync_result.h
new file mode 100644
index 0000000..cdb751e
--- /dev/null
+++ b/chromeos/services/device_sync/cryptauth_device_sync_result.h
@@ -0,0 +1,67 @@
+// Copyright 2019 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.
+
+#ifndef CHROMEOS_SERVICES_DEVICE_SYNC_CRYPTAUTH_DEVICE_SYNC_RESULT_H_
+#define CHROMEOS_SERVICES_DEVICE_SYNC_CRYPTAUTH_DEVICE_SYNC_RESULT_H_
+
+#include <ostream>
+
+#include "base/optional.h"
+#include "chromeos/services/device_sync/proto/cryptauth_directive.pb.h"
+
+namespace chromeos {
+
+namespace device_sync {
+
+// Information about the result of a CryptAuth v2 DeviceSync attempt.
+//
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused. If entries are added, kMaxValue should
+// be updated.
+class CryptAuthDeviceSyncResult {
+ public:
+  // Enum class to denote the result of a CryptAuth v2 DeviceSync attempt.
+  // These values are persisted to logs. Entries should not be renumbered and
+  // numeric values should never be reused. If entries are added, kMaxValue
+  // should be updated.
+  // TODO(nohle): Add more values after DeviceSync flow is implemented.
+  enum class ResultCode {
+    kSuccess = 0,
+    kError = 1,
+    // Used for UMA logs.
+    kMaxValue = kError
+  };
+
+  CryptAuthDeviceSyncResult(
+      ResultCode result_code,
+      const base::Optional<cryptauthv2::ClientDirective>& client_directive);
+  CryptAuthDeviceSyncResult(const CryptAuthDeviceSyncResult& other);
+
+  ~CryptAuthDeviceSyncResult();
+
+  ResultCode result_code() const { return result_code_; }
+
+  const base::Optional<cryptauthv2::ClientDirective>& client_directive() const {
+    return client_directive_;
+  }
+
+  bool IsSuccess() const;
+
+  bool operator==(const CryptAuthDeviceSyncResult& other) const;
+  bool operator!=(const CryptAuthDeviceSyncResult& other) const;
+
+ private:
+  ResultCode result_code_;
+  base::Optional<cryptauthv2::ClientDirective> client_directive_;
+};
+
+std::ostream& operator<<(
+    std::ostream& stream,
+    const CryptAuthDeviceSyncResult::ResultCode result_code);
+
+}  // namespace device_sync
+
+}  // namespace chromeos
+
+#endif  // CHROMEOS_SERVICES_DEVICE_SYNC_CRYPTAUTH_DEVICE_SYNC_RESULT_H_
diff --git a/chromeos/services/device_sync/cryptauth_enrollment_result.h b/chromeos/services/device_sync/cryptauth_enrollment_result.h
index 3bd61ea..7b702a3 100644
--- a/chromeos/services/device_sync/cryptauth_enrollment_result.h
+++ b/chromeos/services/device_sync/cryptauth_enrollment_result.h
@@ -15,13 +15,12 @@
 namespace device_sync {
 
 // Information about the result of a CryptAuth v2 Enrollment attempt.
-//
-// These values are persisted to logs. Entries should not be renumbered and
-// numeric values should never be reused. If entries are added, kMaxValue should
-// be updated.
 class CryptAuthEnrollmentResult {
  public:
-  // Enum class to denote the result of a CryptAuth v2 Enrollment attempt
+  // Enum class to denote the result of a CryptAuth v2 Enrollment attempt.
+  // These values are persisted to logs. Entries should not be renumbered and
+  // numeric values should never be reused. If entries are added, kMaxValue
+  // should be updated.
   enum class ResultCode {
     // Successfully synced but no new keys were requested by CryptAuth, so no
     // EnrollKeysRequest was made.
diff --git a/components/arc/intent_helper/arc_intent_helper_bridge.cc b/components/arc/intent_helper/arc_intent_helper_bridge.cc
index 56f860b..251884d 100644
--- a/components/arc/intent_helper/arc_intent_helper_bridge.cc
+++ b/components/arc/intent_helper/arc_intent_helper_bridge.cc
@@ -8,8 +8,7 @@
 #include <utility>
 
 #include "ash/public/cpp/new_window_delegate.h"
-#include "ash/public/interfaces/constants.mojom.h"
-#include "ash/public/interfaces/wallpaper.mojom.h"
+#include "ash/public/cpp/wallpaper_controller.h"
 #include "base/logging.h"
 #include "base/memory/singleton.h"
 #include "base/memory/weak_ptr.h"
@@ -229,11 +228,7 @@
 void ArcIntentHelperBridge::OpenWallpaperPicker() {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   RecordOpenType(ArcIntentHelperOpenType::WALLPAPER_PICKER);
-  ash::mojom::WallpaperControllerPtr wallpaper_controller_ptr;
-  content::ServiceManagerConnection::GetForProcess()
-      ->GetConnector()
-      ->BindInterface(ash::mojom::kServiceName, &wallpaper_controller_ptr);
-  wallpaper_controller_ptr->OpenWallpaperPickerIfAllowed();
+  ash::WallpaperController::Get()->OpenWallpaperPickerIfAllowed();
 }
 
 void ArcIntentHelperBridge::SetWallpaperDeprecated(
diff --git a/components/autofill/ios/browser/BUILD.gn b/components/autofill/ios/browser/BUILD.gn
index f6a9a04..21b5d47 100644
--- a/components/autofill/ios/browser/BUILD.gn
+++ b/components/autofill/ios/browser/BUILD.gn
@@ -42,6 +42,7 @@
     "//google_apis",
     "//ios/web/common",
     "//ios/web/public",
+    "//ios/web/public/deprecated",
     "//ios/web/public/js_messaging",
     "//ios/web/public/security",
     "//services/network/public/cpp",
@@ -88,6 +89,7 @@
     "//components/leveldb_proto:leveldb_proto",
     "//components/prefs",
     "//ios/web/public",
+    "//ios/web/public/deprecated",
     "//ios/web/public/js_messaging",
     "//ios/web/public/test",
     "//ios/web/public/test/fakes",
diff --git a/components/autofill/ios/browser/autofill_agent.mm b/components/autofill/ios/browser/autofill_agent.mm
index 91e6bb5..4be7d25 100644
--- a/components/autofill/ios/browser/autofill_agent.mm
+++ b/components/autofill/ios/browser/autofill_agent.mm
@@ -45,13 +45,13 @@
 #import "components/prefs/ios/pref_observer_bridge.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "components/prefs/pref_service.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
+#include "ios/web/public/deprecated/url_verification_constants.h"
 #include "ios/web/public/js_messaging/web_frame.h"
 #include "ios/web/public/js_messaging/web_frame_util.h"
 #import "ios/web/public/js_messaging/web_frames_manager.h"
 #include "ios/web/public/url_scheme_util.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
 #import "ios/web/public/web_state/navigation_context.h"
-#include "ios/web/public/web_state/url_verification_constants.h"
 #import "ios/web/public/web_state/web_state.h"
 #import "ios/web/public/web_state/web_state_observer_bridge.h"
 #include "ui/gfx/geometry/rect.h"
diff --git a/components/autofill/ios/browser/autofill_agent_unittests.mm b/components/autofill/ios/browser/autofill_agent_unittests.mm
index 864c9f4d1..5001b9a 100644
--- a/components/autofill/ios/browser/autofill_agent_unittests.mm
+++ b/components/autofill/ios/browser/autofill_agent_unittests.mm
@@ -17,12 +17,12 @@
 #include "components/autofill/ios/browser/autofill_driver_ios.h"
 #import "components/autofill/ios/browser/js_autofill_manager.h"
 #include "components/prefs/pref_service.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #include "ios/web/public/js_messaging/web_frame_util.h"
 #include "ios/web/public/test/fakes/fake_web_frame.h"
 #include "ios/web/public/test/fakes/test_browser_state.h"
 #import "ios/web/public/test/fakes/test_web_state.h"
 #include "ios/web/public/test/test_web_thread_bundle.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #import "testing/gtest_mac.h"
diff --git a/components/autofill/ios/browser/autofill_util.mm b/components/autofill/ios/browser/autofill_util.mm
index f17d294..8a8e7713 100644
--- a/components/autofill/ios/browser/autofill_util.mm
+++ b/components/autofill/ios/browser/autofill_util.mm
@@ -18,10 +18,10 @@
 #include "components/autofill/core/common/autofill_util.h"
 #include "components/autofill/core/common/form_data.h"
 #include "components/autofill/core/common/form_field_data.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #import "ios/web/public/navigation_item.h"
 #import "ios/web/public/navigation_manager.h"
 #include "ios/web/public/security/ssl_status.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
diff --git a/components/autofill/ios/browser/js_autofill_manager.h b/components/autofill/ios/browser/js_autofill_manager.h
index 6be079b..15c404b 100644
--- a/components/autofill/ios/browser/js_autofill_manager.h
+++ b/components/autofill/ios/browser/js_autofill_manager.h
@@ -8,7 +8,7 @@
 #include "base/ios/block_types.h"
 #include "base/values.h"
 #include "components/autofill/core/common/autofill_constants.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 
 namespace web {
 class WebFrame;
diff --git a/components/autofill/ios/browser/js_suggestion_manager.h b/components/autofill/ios/browser/js_suggestion_manager.h
index 1a4256c..953742fe 100644
--- a/components/autofill/ios/browser/js_suggestion_manager.h
+++ b/components/autofill/ios/browser/js_suggestion_manager.h
@@ -5,7 +5,7 @@
 #ifndef COMPONENTS_AUTOFILL_IOS_BROWSER_JS_SUGGESTION_MANAGER_H_
 #define COMPONENTS_AUTOFILL_IOS_BROWSER_JS_SUGGESTION_MANAGER_H_
 
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 
 namespace web {
 class WebFramesManager;
diff --git a/components/autofill/ios/browser/js_suggestion_manager.mm b/components/autofill/ios/browser/js_suggestion_manager.mm
index 40abf79d..07a81ca2 100644
--- a/components/autofill/ios/browser/js_suggestion_manager.mm
+++ b/components/autofill/ios/browser/js_suggestion_manager.mm
@@ -14,9 +14,9 @@
 #include "base/strings/sys_string_conversions.h"
 #include "base/values.h"
 #import "components/autofill/ios/browser/autofill_util.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #include "ios/web/public/js_messaging/web_frame.h"
 #include "ios/web/public/js_messaging/web_frames_manager.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
diff --git a/components/components_strings.grd b/components/components_strings.grd
index ed2cf8e..b334ee32 100644
--- a/components/components_strings.grd
+++ b/components/components_strings.grd
@@ -287,6 +287,16 @@
           Not Now
         </message>
       </if>
+      <if expr="not use_titlecase">
+        <message name="IDS_TURN_OFF" desc="Used on a button that turns off a function.">
+          Turn off
+        </message>
+      </if>
+      <if expr="use_titlecase">
+        <message name="IDS_TURN_OFF" desc="In Title Case: Used on a button that turns off a function.">
+          Turn Off
+        </message>
+      </if>
 
       <message name="IDS_PLUGIN_NOT_SUPPORTED" desc="The placeholder text for an unsupported plugin.">
         This plugin is not supported
diff --git a/components/components_strings_grd/IDS_TURN_OFF.png.sha1 b/components/components_strings_grd/IDS_TURN_OFF.png.sha1
new file mode 100644
index 0000000..0e5d97e
--- /dev/null
+++ b/components/components_strings_grd/IDS_TURN_OFF.png.sha1
@@ -0,0 +1 @@
+db1700a2a9452a95045a6e70e76e1178feb0f61e
\ No newline at end of file
diff --git a/components/content_capture/common/content_capture_data.h b/components/content_capture/common/content_capture_data.h
index 6ed0880..8a7f219c 100644
--- a/components/content_capture/common/content_capture_data.h
+++ b/components/content_capture/common/content_capture_data.h
@@ -15,15 +15,20 @@
 // This struct defines the on-screen text content and its bounds in a frame,
 // the text is captured in renderer and sent to browser; the root of
 // this tree is frame, the child could be the scrollable area or the text
-// content.
+// content, scrollable area can have scrollable area or text as child. Text
+// cannot have any child.
 struct ContentCaptureData {
   ContentCaptureData();
   ContentCaptureData(const ContentCaptureData& data);
   ~ContentCaptureData();
 
-  // The id of the frame or the content.
+  // The id of the frame or the content,
+  // For frame, this will be 0 until ContentCaptureReceiver assigns a unique ID.
   int64_t id = 0;
   // The url of frame or the text of the content.
+  // For frame, this is the URL of the frame.
+  // For scrollable area, this is not used.
+  // For text, this is the text value.
   base::string16 value;
   // The bounds of the frame or the content.
   gfx::Rect bounds;
@@ -38,6 +43,9 @@
 };
 
 // This defines a session, is a list of frames from current frame to root.
+// This represents the frame hierarchy, starting from the current frame to the
+// root frame, in the upward order. Note that ContentCaptureData here can only
+// have URL as value, and no ContentCaptureData has children in it.
 using ContentCaptureSession = std::vector<ContentCaptureData>;
 
 }  // namespace content_capture
diff --git a/components/dom_distiller/ios/BUILD.gn b/components/dom_distiller/ios/BUILD.gn
index 8c796ad..0bfc6a6c 100644
--- a/components/dom_distiller/ios/BUILD.gn
+++ b/components/dom_distiller/ios/BUILD.gn
@@ -16,7 +16,8 @@
     "//components/dom_distiller/core",
     "//components/dom_distiller/core/proto",
     "//components/favicon/ios",
-    "//ios/web",
+    "//ios/web/public",
+    "//ios/web/public/deprecated",
     "//url",
   ]
 }
diff --git a/components/dom_distiller/ios/distiller_page_ios.mm b/components/dom_distiller/ios/distiller_page_ios.mm
index 9d7466728..248a76e 100644
--- a/components/dom_distiller/ios/distiller_page_ios.mm
+++ b/components/dom_distiller/ios/distiller_page_ios.mm
@@ -17,9 +17,9 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
 #include "ios/web/public/browser_state.h"
+#import "ios/web/public/deprecated/crw_js_injection_manager.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #import "ios/web/public/navigation_manager.h"
-#import "ios/web/public/web_state/js/crw_js_injection_manager.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
 #import "ios/web/public/web_state/web_state.h"
 #include "ios/web/public/web_state/web_state_observer.h"
 #import "ios/web/public/web_state/web_state_policy_decider.h"
diff --git a/components/gwp_asan/client/BUILD.gn b/components/gwp_asan/client/BUILD.gn
index 28647ade..6769a8e3 100644
--- a/components/gwp_asan/client/BUILD.gn
+++ b/components/gwp_asan/client/BUILD.gn
@@ -13,6 +13,8 @@
     "guarded_page_allocator_win.cc",
     "gwp_asan.cc",
     "gwp_asan.h",
+    "sampling_helpers.cc",
+    "sampling_helpers.h",
     "sampling_state.h",
   ]
 
@@ -49,6 +51,7 @@
   sources = [
     "guarded_page_allocator_unittest.cc",
     "gwp_asan_unittest.cc",
+    "sampling_helpers_unittest.cc",
   ]
 
   if (use_allocator_shim) {
diff --git a/components/gwp_asan/client/gwp_asan.cc b/components/gwp_asan/client/gwp_asan.cc
index 3681f104..aa505236 100644
--- a/components/gwp_asan/client/gwp_asan.cc
+++ b/components/gwp_asan/client/gwp_asan.cc
@@ -21,6 +21,7 @@
 #include "base/strings/stringprintf.h"
 #include "build/build_config.h"
 #include "components/gwp_asan/client/guarded_page_allocator.h"
+#include "components/gwp_asan/client/sampling_helpers.h"
 
 #if BUILDFLAG(USE_ALLOCATOR_SHIM)
 #include "components/gwp_asan/client/sampling_malloc_shims.h"
@@ -178,7 +179,7 @@
 
 }  // namespace internal
 
-void EnableForMalloc(bool boost_sampling) {
+void EnableForMalloc(bool boost_sampling, const char* process_type) {
 #if BUILDFLAG(USE_ALLOCATOR_SHIM)
   static bool init_once = [&]() -> bool {
     auto settings = internal::GetAllocatorSettings(internal::kGwpAsanMalloc,
@@ -186,9 +187,11 @@
     if (!settings)
       return false;
 
-    internal::InstallMallocHooks(settings->max_allocated_pages,
-                                 settings->num_metadata, settings->total_pages,
-                                 settings->sampling_frequency);
+    internal::InstallMallocHooks(
+        settings->max_allocated_pages, settings->num_metadata,
+        settings->total_pages, settings->sampling_frequency,
+        internal::CreateOomCallback("Malloc", process_type,
+                                    settings->sampling_frequency));
     return true;
   }();
   ignore_result(init_once);
@@ -198,7 +201,7 @@
 #endif  // BUILDFLAG(USE_ALLOCATOR_SHIM)
 }
 
-void EnableForPartitionAlloc(bool boost_sampling) {
+void EnableForPartitionAlloc(bool boost_sampling, const char* process_type) {
 #if BUILDFLAG(USE_PARTITION_ALLOC)
   static bool init_once = [&]() -> bool {
     auto settings = internal::GetAllocatorSettings(
@@ -208,7 +211,9 @@
 
     internal::InstallPartitionAllocHooks(
         settings->max_allocated_pages, settings->num_metadata,
-        settings->total_pages, settings->sampling_frequency);
+        settings->total_pages, settings->sampling_frequency,
+        internal::CreateOomCallback("PartitionAlloc", process_type,
+                                    settings->sampling_frequency));
     return true;
   }();
   ignore_result(init_once);
diff --git a/components/gwp_asan/client/gwp_asan.h b/components/gwp_asan/client/gwp_asan.h
index 82bed99f..be51d84 100644
--- a/components/gwp_asan/client/gwp_asan.h
+++ b/components/gwp_asan/client/gwp_asan.h
@@ -24,10 +24,14 @@
 // Enable GWP-ASan for the current process for the given allocator. This should
 // only be called once per process. This can not be disabled once it has been
 // enabled. The |boost_sampling| parameter is used to indicate if the caller
-// wants to increase the sampling for this process.
+// wants to increase the sampling for this process. The |process_type| parameter
+// should be equal to the string passed to --type=, it is used for reporting
+// metrics broken out per-process.
 
-GWP_ASAN_EXPORT void EnableForMalloc(bool boost_sampling);
-GWP_ASAN_EXPORT void EnableForPartitionAlloc(bool boost_sampling);
+GWP_ASAN_EXPORT void EnableForMalloc(bool boost_sampling,
+                                     const char* process_type);
+GWP_ASAN_EXPORT void EnableForPartitionAlloc(bool boost_sampling,
+                                             const char* process_type);
 
 }  // namespace gwp_asan
 
diff --git a/components/gwp_asan/client/sampling_helpers.cc b/components/gwp_asan/client/sampling_helpers.cc
new file mode 100644
index 0000000..052aa7e8
--- /dev/null
+++ b/components/gwp_asan/client/sampling_helpers.cc
@@ -0,0 +1,71 @@
+// Copyright 2019 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 "components/gwp_asan/client/sampling_helpers.h"
+
+#include <string>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/metrics/histogram_functions.h"
+#include "base/numerics/safe_math.h"
+#include "base/strings/stringprintf.h"
+
+namespace gwp_asan {
+namespace internal {
+
+namespace {
+
+// Turns the value passed to --type= into a string used in a histogram name for
+// common processes, or nullptr otherwise.
+const char* ProcessString(const char* process_type) {
+  if (!process_type)
+    return nullptr;
+  if (!strcmp(process_type, ""))
+    return "Browser";
+  if (!strcmp(process_type, "extension"))
+    return "Extension";
+  if (!strcmp(process_type, "gpu-process"))
+    return "Gpu";
+  if (!strcmp(process_type, "ppapi"))
+    return "Ppapi";
+  if (!strcmp(process_type, "renderer"))
+    return "Renderer";
+  if (!strcmp(process_type, "utility"))
+    return "Utility";
+  return nullptr;
+}
+
+void ReportOomHistogram(std::string histogram_name,
+                        size_t sampling_frequency,
+                        size_t allocations) {
+  base::CheckedNumeric<int> total_allocations = allocations;
+  total_allocations *= sampling_frequency;
+  if (total_allocations.IsValid()) {
+    base::UmaHistogramCustomCounts(/*name=*/histogram_name,
+                                   /*sample=*/total_allocations.ValueOrDie(),
+                                   /*min=*/1, /*max=*/100000000,
+                                   /*buckets=*/100);
+  }
+}
+
+}  // namespace
+
+GuardedPageAllocator::OutOfMemoryCallback CreateOomCallback(
+    const char* allocator_name,
+    const char* process_type,
+    size_t sampling_frequency) {
+  const char* process_str = ProcessString(process_type);
+  if (!process_str)
+    return base::DoNothing();
+
+  std::string histogram_name = base::StringPrintf("GwpAsan.AllocatorOom.%s.%s",
+                                                  allocator_name, process_str);
+  return base::BindOnce(&ReportOomHistogram, std::move(histogram_name),
+                        sampling_frequency);
+}
+
+}  // namespace internal
+}  // namespace gwp_asan
diff --git a/components/gwp_asan/client/sampling_helpers.h b/components/gwp_asan/client/sampling_helpers.h
new file mode 100644
index 0000000..1c3f6269
--- /dev/null
+++ b/components/gwp_asan/client/sampling_helpers.h
@@ -0,0 +1,23 @@
+// Copyright (c) 2019 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.
+
+#ifndef COMPONENTS_GWP_ASAN_CLIENT_SAMPLING_HELPERS_H_
+#define COMPONENTS_GWP_ASAN_CLIENT_SAMPLING_HELPERS_H_
+
+#include "components/gwp_asan/client/export.h"
+#include "components/gwp_asan/client/guarded_page_allocator.h"
+
+namespace gwp_asan {
+namespace internal {
+
+// Create a callback for GuardedPageAllocator that reports allocator OOM.
+GWP_ASAN_EXPORT GuardedPageAllocator::OutOfMemoryCallback CreateOomCallback(
+    const char* allocator_name,
+    const char* process_type,
+    size_t sampling_frequency);
+
+}  // namespace internal
+}  // namespace gwp_asan
+
+#endif  // COMPONENTS_GWP_ASAN_CLIENT_SAMPLING_HELPERS_H_
diff --git a/components/gwp_asan/client/sampling_helpers_unittest.cc b/components/gwp_asan/client/sampling_helpers_unittest.cc
new file mode 100644
index 0000000..fd546f6
--- /dev/null
+++ b/components/gwp_asan/client/sampling_helpers_unittest.cc
@@ -0,0 +1,43 @@
+// Copyright 2019 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 "components/gwp_asan/client/sampling_helpers.h"
+
+#include "base/test/gtest_util.h"
+#include "base/test/metrics/histogram_tester.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace gwp_asan {
+namespace internal {
+
+TEST(SamplingHelpers, BasicFunctionality) {
+  constexpr size_t kSamplingFrequency = 10;
+  constexpr size_t kAllocationsBeforeOom = 15;
+
+  base::HistogramTester histogram_tester;
+
+  CreateOomCallback("Foo", "", kSamplingFrequency).Run(kAllocationsBeforeOom);
+  CreateOomCallback("Bar", "utility", kSamplingFrequency)
+      .Run(kAllocationsBeforeOom);
+  // Ignore unknown process types
+  CreateOomCallback("Baz", "UNKNOWN", kSamplingFrequency)
+      .Run(kAllocationsBeforeOom);
+
+  base::HistogramTester::CountsMap expected_counts;
+  expected_counts["GwpAsan.AllocatorOom.Foo.Browser"] = 1;
+  expected_counts["GwpAsan.AllocatorOom.Bar.Utility"] = 1;
+  EXPECT_THAT(histogram_tester.GetTotalCountsForPrefix("GwpAsan.AllocatorOom"),
+              testing::ContainerEq(expected_counts));
+
+  histogram_tester.ExpectUniqueSample(
+      "GwpAsan.AllocatorOom.Foo.Browser",
+      kSamplingFrequency * kAllocationsBeforeOom, 1);
+  histogram_tester.ExpectUniqueSample(
+      "GwpAsan.AllocatorOom.Bar.Utility",
+      kSamplingFrequency * kAllocationsBeforeOom, 1);
+}
+
+}  // namespace internal
+}  // namespace gwp_asan
diff --git a/components/gwp_asan/client/sampling_malloc_shims.cc b/components/gwp_asan/client/sampling_malloc_shims.cc
index 93ca9a210..7cab0182 100644
--- a/components/gwp_asan/client/sampling_malloc_shims.cc
+++ b/components/gwp_asan/client/sampling_malloc_shims.cc
@@ -5,9 +5,9 @@
 #include "components/gwp_asan/client/sampling_malloc_shims.h"
 
 #include <algorithm>
+#include <utility>
 
 #include "base/allocator/allocator_shim.h"
-#include "base/bind_helpers.h"
 #include "base/compiler_specific.h"
 #include "base/logging.h"
 #include "base/no_destructor.h"
@@ -252,10 +252,11 @@
 void InstallMallocHooks(size_t max_allocated_pages,
                         size_t num_metadata,
                         size_t total_pages,
-                        size_t sampling_frequency) {
+                        size_t sampling_frequency,
+                        GuardedPageAllocator::OutOfMemoryCallback callback) {
   static crash_reporter::CrashKeyString<24> malloc_crash_key(kMallocCrashKey);
   gpa = new GuardedPageAllocator();
-  gpa->Init(max_allocated_pages, num_metadata, total_pages, base::DoNothing(),
+  gpa->Init(max_allocated_pages, num_metadata, total_pages, std::move(callback),
             false);
   malloc_crash_key.Set(gpa->GetCrashKey());
   sampling_state.Init(sampling_frequency);
diff --git a/components/gwp_asan/client/sampling_malloc_shims.h b/components/gwp_asan/client/sampling_malloc_shims.h
index 8fb1090..9f5384f 100644
--- a/components/gwp_asan/client/sampling_malloc_shims.h
+++ b/components/gwp_asan/client/sampling_malloc_shims.h
@@ -9,16 +9,19 @@
 
 #include "build/build_config.h"
 #include "components/gwp_asan/client/export.h"
+#include "components/gwp_asan/client/guarded_page_allocator.h"
 
 namespace gwp_asan {
 namespace internal {
 
 // Initialize the guarded allocator with the given parameters, and install the
 // sampling malloc shims with the provided sampling frequency.
-GWP_ASAN_EXPORT void InstallMallocHooks(size_t max_allocated_pages,
-                                        size_t num_metadata,
-                                        size_t total_pages,
-                                        size_t sampling_frequency);
+GWP_ASAN_EXPORT void InstallMallocHooks(
+    size_t max_allocated_pages,
+    size_t num_metadata,
+    size_t total_pages,
+    size_t sampling_frequency,
+    GuardedPageAllocator::OutOfMemoryCallback callback);
 
 }  // namespace internal
 
diff --git a/components/gwp_asan/client/sampling_malloc_shims_unittest.cc b/components/gwp_asan/client/sampling_malloc_shims_unittest.cc
index aaaea76..7dd943e 100644
--- a/components/gwp_asan/client/sampling_malloc_shims_unittest.cc
+++ b/components/gwp_asan/client/sampling_malloc_shims_unittest.cc
@@ -10,6 +10,7 @@
 #include <string>
 
 #include "base/allocator/allocator_shim.h"
+#include "base/bind_helpers.h"
 #include "base/process/process_metrics.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/test/gtest_util.h"
@@ -68,7 +69,7 @@
     crash_reporter::InitializeCrashKeys();
     InstallMallocHooks(AllocatorState::kMaxMetadata,
                        AllocatorState::kMaxMetadata, AllocatorState::kMaxSlots,
-                       kSamplingFrequency);
+                       kSamplingFrequency, base::DoNothing());
   }
 
  protected:
diff --git a/components/gwp_asan/client/sampling_partitionalloc_shims.cc b/components/gwp_asan/client/sampling_partitionalloc_shims.cc
index 517b88e..f6cf456f 100644
--- a/components/gwp_asan/client/sampling_partitionalloc_shims.cc
+++ b/components/gwp_asan/client/sampling_partitionalloc_shims.cc
@@ -5,9 +5,9 @@
 #include "components/gwp_asan/client/sampling_partitionalloc_shims.h"
 
 #include <algorithm>
+#include <utility>
 
 #include "base/allocator/partition_allocator/partition_alloc.h"
-#include "base/bind_helpers.h"
 #include "base/logging.h"
 #include "base/partition_alloc_buildflags.h"
 #include "components/crash/core/common/crash_key.h"
@@ -67,14 +67,16 @@
   return *gpa;
 }
 
-void InstallPartitionAllocHooks(size_t max_allocated_pages,
-                                size_t num_metadata,
-                                size_t total_pages,
-                                size_t sampling_frequency) {
+void InstallPartitionAllocHooks(
+    size_t max_allocated_pages,
+    size_t num_metadata,
+    size_t total_pages,
+    size_t sampling_frequency,
+    GuardedPageAllocator::OutOfMemoryCallback callback) {
   static crash_reporter::CrashKeyString<24> pa_crash_key(
       kPartitionAllocCrashKey);
   gpa = new GuardedPageAllocator();
-  gpa->Init(max_allocated_pages, num_metadata, total_pages, base::DoNothing(),
+  gpa->Init(max_allocated_pages, num_metadata, total_pages, std::move(callback),
             true);
   pa_crash_key.Set(gpa->GetCrashKey());
   sampling_state.Init(sampling_frequency);
diff --git a/components/gwp_asan/client/sampling_partitionalloc_shims.h b/components/gwp_asan/client/sampling_partitionalloc_shims.h
index 0182b5a..c8682e0 100644
--- a/components/gwp_asan/client/sampling_partitionalloc_shims.h
+++ b/components/gwp_asan/client/sampling_partitionalloc_shims.h
@@ -8,14 +8,17 @@
 #include <stddef.h>  // for size_t
 
 #include "components/gwp_asan/client/export.h"
+#include "components/gwp_asan/client/guarded_page_allocator.h"
 
 namespace gwp_asan {
 namespace internal {
 
-GWP_ASAN_EXPORT void InstallPartitionAllocHooks(size_t max_allocated_pages,
-                                                size_t num_metadata,
-                                                size_t total_pages,
-                                                size_t sampling_frequency);
+GWP_ASAN_EXPORT void InstallPartitionAllocHooks(
+    size_t max_allocated_pages,
+    size_t num_metadata,
+    size_t total_pages,
+    size_t sampling_frequency,
+    GuardedPageAllocator::OutOfMemoryCallback callback);
 
 }  // namespace internal
 }  // namespace gwp_asan
diff --git a/components/gwp_asan/client/sampling_partitionalloc_shims_unittest.cc b/components/gwp_asan/client/sampling_partitionalloc_shims_unittest.cc
index 8828738e..91b842e 100644
--- a/components/gwp_asan/client/sampling_partitionalloc_shims_unittest.cc
+++ b/components/gwp_asan/client/sampling_partitionalloc_shims_unittest.cc
@@ -11,6 +11,7 @@
 #include <string>
 
 #include "base/allocator/partition_allocator/partition_alloc.h"
+#include "base/bind_helpers.h"
 #include "base/partition_alloc_buildflags.h"
 #include "base/process/process_metrics.h"
 #include "base/strings/string_number_conversions.h"
@@ -53,9 +54,9 @@
  public:
   static void multiprocessTestSetup() {
     crash_reporter::InitializeCrashKeys();
-    InstallPartitionAllocHooks(AllocatorState::kMaxMetadata,
-                               AllocatorState::kMaxMetadata,
-                               AllocatorState::kMaxSlots, kSamplingFrequency);
+    InstallPartitionAllocHooks(
+        AllocatorState::kMaxMetadata, AllocatorState::kMaxMetadata,
+        AllocatorState::kMaxSlots, kSamplingFrequency, base::DoNothing());
   }
 
  protected:
diff --git a/components/gwp_asan/crash_handler/crash_analyzer.cc b/components/gwp_asan/crash_handler/crash_analyzer.cc
index 3cf146b..9d42882 100644
--- a/components/gwp_asan/crash_handler/crash_analyzer.cc
+++ b/components/gwp_asan/crash_handler/crash_analyzer.cc
@@ -255,6 +255,7 @@
                          metadata.dealloc, proto->mutable_deallocation());
   }
 
+  ReportHistogram(allocator, GwpAsanCrashAnalysisResult::kGwpAsanCrash);
   return true;
 }
 
diff --git a/components/gwp_asan/crash_handler/crash_analyzer_unittest.cc b/components/gwp_asan/crash_handler/crash_analyzer_unittest.cc
index 680b9d8..2e8da2d 100644
--- a/components/gwp_asan/crash_handler/crash_analyzer_unittest.cc
+++ b/components/gwp_asan/crash_handler/crash_analyzer_unittest.cc
@@ -100,7 +100,9 @@
       CrashAnalyzer::GetExceptionInfo(process_snapshot_, &proto);
   ASSERT_TRUE(proto_present);
 
-  histogram_tester.ExpectTotalCount(kMallocHistogramName, 0);
+  int result = static_cast<int>(GwpAsanCrashAnalysisResult::kGwpAsanCrash);
+  EXPECT_THAT(histogram_tester.GetAllSamples(kMallocHistogramName),
+              testing::ElementsAre(base::Bucket(result, 1)));
   histogram_tester.ExpectTotalCount(kPartitionAllocHistogramName, 0);
 
   ASSERT_TRUE(proto.has_allocation());
diff --git a/components/omnibox/browser/autocomplete_provider.cc b/components/omnibox/browser/autocomplete_provider.cc
index 085f64e1..570bfcc 100644
--- a/components/omnibox/browser/autocomplete_provider.cc
+++ b/components/omnibox/browser/autocomplete_provider.cc
@@ -85,7 +85,7 @@
   if (text.empty())
     return original_class;
 
-  TermMatches term_matches = FindTermMatches(find_text, text, true, false);
+  TermMatches term_matches = FindTermMatches(find_text, text);
 
   ACMatchClassifications classifications;
   if (text_is_search_query) {
diff --git a/components/omnibox/browser/document_provider.cc b/components/omnibox/browser/document_provider.cc
index 85e4549..95df411 100644
--- a/components/omnibox/browser/document_provider.cc
+++ b/components/omnibox/browser/document_provider.cc
@@ -532,7 +532,7 @@
 ACMatchClassifications DocumentProvider::Classify(
     const base::string16& text,
     const base::string16& input_text) {
-  TermMatches term_matches = FindTermMatches(input_text, text, true, false);
+  TermMatches term_matches = FindTermMatches(input_text, text);
   return ClassifyTermMatches(term_matches, text.size(),
                              ACMatchClassification::MATCH,
                              ACMatchClassification::NONE);
diff --git a/components/omnibox/browser/history_url_provider.cc b/components/omnibox/browser/history_url_provider.cc
index 5e31931..12ad551 100644
--- a/components/omnibox/browser/history_url_provider.cc
+++ b/components/omnibox/browser/history_url_provider.cc
@@ -731,8 +731,7 @@
 ACMatchClassifications HistoryURLProvider::ClassifyDescription(
     const base::string16& input_text,
     const base::string16& description) {
-  TermMatches term_matches =
-      FindTermMatches(input_text, description, true, false);
+  TermMatches term_matches = FindTermMatches(input_text, description);
   return ClassifyTermMatches(term_matches, description.size(),
                              ACMatchClassification::MATCH,
                              ACMatchClassification::NONE);
diff --git a/components/omnibox/browser/search_provider.h b/components/omnibox/browser/search_provider.h
index 7552e97c..f4f9090 100644
--- a/components/omnibox/browser/search_provider.h
+++ b/components/omnibox/browser/search_provider.h
@@ -88,6 +88,9 @@
                            DontInlineAutocompleteAsynchronously);
   FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, NavigationInline);
   FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, NavigationInlineDomainClassify);
+  FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, NavigationPrefixClassify);
+  FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, NavigationMidWordClassify);
+  FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, NavigationWordBreakClassify);
   FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, NavigationInlineSchemeSubstring);
   FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, SuggestRelevanceExperiment);
   FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, TestDeleteMatch);
diff --git a/components/omnibox/browser/search_suggestion_parser.cc b/components/omnibox/browser/search_suggestion_parser.cc
index 9c347691..2b000b9 100644
--- a/components/omnibox/browser/search_suggestion_parser.cc
+++ b/components/omnibox/browser/search_suggestion_parser.cc
@@ -251,37 +251,33 @@
     return;
   }
 
-  // First look for the user's input inside the formatted url as it would be
-  // without trimming the scheme, so we can find matches at the beginning of the
-  // scheme.
-  const URLPrefix* prefix =
-      URLPrefix::BestURLPrefix(formatted_url_, input_text);
-  size_t match_start = (prefix == nullptr) ? formatted_url_.find(input_text)
-                                           : prefix->prefix.length();
-
+  // Set contents to the formatted URL while ensuring the scheme and subdomain
+  // are kept if the user text seems to include them. E.g., for the user text
+  // 'http google.com', the contents should not trim 'http'.
   bool match_in_scheme = false;
   bool match_in_subdomain = false;
-  AutocompleteMatch::GetMatchComponents(
-      GURL(formatted_url_), {{match_start, match_start + input_text.length()}},
-      &match_in_scheme, &match_in_subdomain);
+  TermMatches term_matches_in_url = FindTermMatches(input_text, formatted_url_);
+  // Convert TermMatches (offset, length) to MatchPosition (start, end).
+  std::vector<AutocompleteMatch::MatchPosition> match_positions;
+  for (auto match : term_matches_in_url)
+    match_positions.emplace_back(match.offset, match.offset + match.length);
+  AutocompleteMatch::GetMatchComponents(GURL(formatted_url_), match_positions,
+                                        &match_in_scheme, &match_in_subdomain);
   auto format_types = AutocompleteMatch::GetFormatTypes(
-      GURL(input_text).has_scheme() || match_in_scheme, match_in_subdomain);
+      GURL(input_text).has_scheme(), match_in_subdomain);
 
-  base::string16 match_contents =
-      url_formatter::FormatUrl(url_, format_types, net::UnescapeRule::SPACES,
-                               nullptr, nullptr, &match_start);
-  // If the first match in the untrimmed string was inside a scheme that we
-  // trimmed, look for a subsequent match.
-  if (match_start == base::string16::npos)
-    match_start = match_contents.find(input_text);
+  // Find matches in the potentially new match_contents
+  base::string16 match_contents = url_formatter::FormatUrl(
+      url_, format_types, net::UnescapeRule::SPACES, nullptr, nullptr, nullptr);
+  TermMatches term_matches = FindTermMatches(input_text, match_contents);
+
   // Update |match_contents_| and |match_contents_class_| if it's allowed.
-  if (allow_bolding_nothing || (match_start != base::string16::npos)) {
+  if (allow_bolding_nothing || !term_matches.empty()) {
     match_contents_ = match_contents;
-    // Safe if |match_start| is npos; also safe if the input is longer than the
-    // remaining contents after |match_start|.
-    AutocompleteMatch::ClassifyLocationInString(match_start,
-        input_text.length(), match_contents_.length(),
-        ACMatchClassification::URL, &match_contents_class_);
+    match_contents_class_ = ClassifyTermMatches(
+        term_matches, match_contents.size(),
+        ACMatchClassification::MATCH | ACMatchClassification::URL,
+        ACMatchClassification::URL);
   }
 }
 
diff --git a/components/password_manager/core/browser/password_store_sync.h b/components/password_manager/core/browser/password_store_sync.h
index de0469a..e0455fc 100644
--- a/components/password_manager/core/browser/password_store_sync.h
+++ b/components/password_manager/core/browser/password_store_sync.h
@@ -48,18 +48,24 @@
 };
 
 // Error values for adding a login to the store.
+// Used in metrics: "PasswordManager.MergeSyncData.AddLoginSyncError" and
+// "PasswordManager.ApplySyncChanges.AddLoginSyncError". These values are
+// persisted to logs. Entries should not be renumbered and numeric values should
+// never be reused.
 enum class AddLoginError {
   // Success.
-  kNone,
+  kNone = 0,
   // Database not available.
-  kDbNotAvailable,
+  kDbNotAvailable = 1,
   // The form doesn't the satisfy the constraints.
-  kConstraintViolation,
+  kConstraintViolation = 2,
   // A service-level failure (e.g., on a platform using a keyring, the keyring
   // is temporarily unavailable).
-  kEncrytionServiceFailure,
+  kEncrytionServiceFailure = 3,
   // Database error.
-  kDbError
+  kDbError = 4,
+
+  kMaxValue = kDbError,
 };
 
 // PasswordStore interface for PasswordSyncableService. It provides access to
diff --git a/components/password_manager/core/browser/sync/password_sync_bridge.cc b/components/password_manager/core/browser/sync/password_sync_bridge.cc
index 3b4b3945..e8f2f85 100644
--- a/components/password_manager/core/browser/sync/password_sync_bridge.cc
+++ b/components/password_manager/core/browser/sync/password_sync_bridge.cc
@@ -431,6 +431,8 @@
       PasswordStoreChangeList changes = password_store_sync_->AddLoginSync(
           PasswordFromEntityChange(*entity_change, /*sync_time=*/time_now),
           &add_login_error);
+      base::UmaHistogramEnumeration(
+          "PasswordManager.MergeSyncData.AddLoginSyncError", add_login_error);
 
       // TODO(crbug.com/939302): It's not yet clear if the DCHECK_LE below is
       // legit. However, recent crashes suggest that 2 changes are returned
@@ -526,6 +528,9 @@
           changes = password_store_sync_->AddLoginSync(
               PasswordFromEntityChange(*entity_change, /*sync_time=*/time_now),
               &add_login_error);
+          base::UmaHistogramEnumeration(
+              "PasswordManager.ApplySyncChanges.AddLoginSyncError",
+              add_login_error);
           // If the addition has been successful, inform the processor about the
           // assigned storage key. AddLoginSync() might return multiple changes
           // and the last one should be the one representing the actual addition
diff --git a/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc b/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc
index eda757d6..38a07ac0 100644
--- a/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc
+++ b/components/password_manager/core/browser/sync/password_sync_bridge_unittest.cc
@@ -121,14 +121,14 @@
 
   PasswordStoreChangeList AddLogin(const autofill::PasswordForm& form,
                                    AddLoginError* error) {
+    if (error) {
+      *error = error_;
+    }
     if (error_ == AddLoginError::kNone) {
       data_[primary_key_] = std::make_unique<autofill::PasswordForm>(form);
       return {
           PasswordStoreChange(PasswordStoreChange::ADD, form, primary_key_++)};
     }
-    if (error) {
-      *error = error_;
-    }
     return PasswordStoreChangeList();
   }
 
diff --git a/components/password_manager/core/browser/sync/password_syncable_service.cc b/components/password_manager/core/browser/sync/password_syncable_service.cc
index 98ae096..12438fb 100644
--- a/components/password_manager/core/browser/sync/password_syncable_service.cc
+++ b/components/password_manager/core/browser/sync/password_syncable_service.cc
@@ -11,6 +11,7 @@
 
 #include "base/auto_reset.h"
 #include "base/location.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/autofill/core/common/password_form.h"
@@ -219,7 +220,7 @@
                            SyncDataFromPassword(*it->second)));
   }
 
-  WriteToPasswordStore(sync_entries);
+  WriteToPasswordStore(sync_entries, /*is_merge=*/true);
   merge_result.set_error(
       sync_processor->ProcessSyncChanges(FROM_HERE, updated_db_entries));
   if (merge_result.error().IsSet()) {
@@ -288,7 +289,7 @@
         specifics.password().client_only_encrypted_data(), time_now, entries);
   }
 
-  WriteToPasswordStore(sync_entries);
+  WriteToPasswordStore(sync_entries, /*is_merge=*/false);
   return syncer::SyncError();
 }
 
@@ -362,13 +363,24 @@
   return true;
 }
 
-void PasswordSyncableService::WriteToPasswordStore(const SyncEntries& entries) {
+void PasswordSyncableService::WriteToPasswordStore(const SyncEntries& entries,
+                                                   bool is_merge) {
   PasswordStoreChangeList changes;
 
   for (const std::unique_ptr<autofill::PasswordForm>& form :
        entries.new_entries) {
-    PasswordStoreChangeList new_changes = password_store_->AddLoginSync(*form);
+    AddLoginError add_login_error;
+    PasswordStoreChangeList new_changes =
+        password_store_->AddLoginSync(*form, &add_login_error);
     changes.insert(changes.end(), new_changes.begin(), new_changes.end());
+    if (is_merge) {
+      base::UmaHistogramEnumeration(
+          "PasswordManager.MergeSyncData.AddLoginSyncError", add_login_error);
+    } else {
+      base::UmaHistogramEnumeration(
+          "PasswordManager.ApplySyncChanges.AddLoginSyncError",
+          add_login_error);
+    }
   }
 
   for (const std::unique_ptr<autofill::PasswordForm>& form :
diff --git a/components/password_manager/core/browser/sync/password_syncable_service.h b/components/password_manager/core/browser/sync/password_syncable_service.h
index bb76250..1173a3c 100644
--- a/components/password_manager/core/browser/sync/password_syncable_service.h
+++ b/components/password_manager/core/browser/sync/password_syncable_service.h
@@ -75,7 +75,7 @@
       PasswordEntryMap* passwords_entry_map) const;
 
   // Uses the |PasswordStore| APIs to change entries.
-  void WriteToPasswordStore(const SyncEntries& entries);
+  void WriteToPasswordStore(const SyncEntries& entries, bool is_merge);
 
   // Examines |data|, an entry in sync db, and updates |sync_entries| or
   // |updated_db_entries| accordingly. An element is removed from
diff --git a/components/password_manager/core/browser/sync/password_syncable_service_unittest.cc b/components/password_manager/core/browser/sync/password_syncable_service_unittest.cc
index 2fdedb6..16c11cf7 100644
--- a/components/password_manager/core/browser/sync/password_syncable_service_unittest.cc
+++ b/components/password_manager/core/browser/sync/password_syncable_service_unittest.cc
@@ -179,7 +179,13 @@
         new PasswordSyncableService(password_store_->GetSyncInterface()));
 
     ON_CALL(*password_store_, AddLoginImpl(HasDateSynced(), _))
-        .WillByDefault(Return(PasswordStoreChangeList()));
+        .WillByDefault([&](const autofill::PasswordForm& form,
+                           password_manager::AddLoginError* error) {
+          if (error) {
+            *error = AddLoginError::kNone;
+          }
+          return PasswordStoreChangeList();
+        });
     ON_CALL(*password_store_, RemoveLoginImpl(_))
         .WillByDefault(Return(PasswordStoreChangeList()));
     ON_CALL(*password_store_, UpdateLoginImpl(HasDateSynced()))
diff --git a/components/password_manager/ios/BUILD.gn b/components/password_manager/ios/BUILD.gn
index 83e9449..78759941 100644
--- a/components/password_manager/ios/BUILD.gn
+++ b/components/password_manager/ios/BUILD.gn
@@ -15,6 +15,7 @@
     "//components/password_manager/core/browser",
     "//components/password_manager/core/browser/form_parsing",
     "//ios/web/public",
+    "//ios/web/public/deprecated",
     "//ios/web/public/js_messaging",
     "//url",
   ]
diff --git a/components/password_manager/ios/js_password_manager.h b/components/password_manager/ios/js_password_manager.h
index f73b5b17..af04334 100644
--- a/components/password_manager/ios/js_password_manager.h
+++ b/components/password_manager/ios/js_password_manager.h
@@ -6,7 +6,7 @@
 #define COMPONENTS_PASSWORD_MANAGER_IOS_JS_PASSWORD_MANAGER_H_
 
 #include "base/ios/block_types.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 
 namespace autofill {
 struct PasswordFormFillData;
diff --git a/components/remote_cocoa/app_shim/BUILD.gn b/components/remote_cocoa/app_shim/BUILD.gn
index 46cbd19..bee6dcb 100644
--- a/components/remote_cocoa/app_shim/BUILD.gn
+++ b/components/remote_cocoa/app_shim/BUILD.gn
@@ -37,6 +37,8 @@
     "native_widget_mac_frameless_nswindow.mm",
     "native_widget_mac_nswindow.h",
     "native_widget_mac_nswindow.mm",
+    "ns_view_ids.h",
+    "ns_view_ids.mm",
     "remote_cocoa_app_shim_export.h",
     "views_nswindow_delegate.h",
     "views_nswindow_delegate.mm",
@@ -46,7 +48,7 @@
     "window_move_loop.mm",
     "window_touch_bar_delegate.h",
   ]
-  defines = [ "VIEWS_BRIDGE_MAC_IMPLEMENTATION" ]
+  defines = [ "REMOTE_COCOA_APP_SHIM_IMPLEMENTATION" ]
   deps = [
     "//base",
     "//base:i18n",
diff --git a/components/remote_cocoa/app_shim/bridged_native_widget_impl.h b/components/remote_cocoa/app_shim/bridged_native_widget_impl.h
index cfc036b..9378a4cc 100644
--- a/components/remote_cocoa/app_shim/bridged_native_widget_impl.h
+++ b/components/remote_cocoa/app_shim/bridged_native_widget_impl.h
@@ -13,6 +13,7 @@
 #import "base/mac/scoped_nsobject.h"
 #include "base/macros.h"
 #import "components/remote_cocoa/app_shim/mouse_capture_delegate.h"
+#include "components/remote_cocoa/app_shim/ns_view_ids.h"
 #include "components/remote_cocoa/app_shim/remote_cocoa_app_shim_export.h"
 #include "components/remote_cocoa/common/bridged_native_widget.mojom.h"
 #include "components/remote_cocoa/common/text_input_host.mojom.h"
@@ -20,7 +21,6 @@
 #include "ui/accelerated_widget_mac/ca_transaction_observer.h"
 #include "ui/accelerated_widget_mac/display_ca_layer_tree.h"
 #include "ui/base/cocoa/command_dispatcher.h"
-#include "ui/base/cocoa/ns_view_ids.h"
 #include "ui/base/ime/text_input_client.h"
 #include "ui/display/display_observer.h"
 
@@ -303,7 +303,7 @@
   base::scoped_nsobject<NSEvent> saved_redispatch_event_;
 
   base::scoped_nsobject<BridgedContentView> bridged_view_;
-  std::unique_ptr<ui::ScopedNSViewIdMapping> bridged_view_id_mapping_;
+  std::unique_ptr<remote_cocoa::ScopedNSViewIdMapping> bridged_view_id_mapping_;
   base::scoped_nsobject<ModalShowAnimationWithLayer> show_animation_;
   std::unique_ptr<CocoaMouseCapture> mouse_capture_;
   std::unique_ptr<CocoaWindowMoveLoop> window_move_loop_;
diff --git a/components/remote_cocoa/app_shim/bridged_native_widget_impl.mm b/components/remote_cocoa/app_shim/bridged_native_widget_impl.mm
index 8ee91afc..a9f2b8a 100644
--- a/components/remote_cocoa/app_shim/bridged_native_widget_impl.mm
+++ b/components/remote_cocoa/app_shim/bridged_native_widget_impl.mm
@@ -535,8 +535,9 @@
 
   bridged_view_.reset([[BridgedContentView alloc] initWithBridge:this
                                                           bounds:bounds]);
-  bridged_view_id_mapping_ = std::make_unique<ui::ScopedNSViewIdMapping>(
-      ns_view_id, bridged_view_.get());
+  bridged_view_id_mapping_ =
+      std::make_unique<remote_cocoa::ScopedNSViewIdMapping>(
+          ns_view_id, bridged_view_.get());
 
   // Objective C initializers can return nil. However, if |view| is non-NULL
   // this should be treated as an error and caught early.
diff --git a/components/remote_cocoa/app_shim/ns_view_ids.h b/components/remote_cocoa/app_shim/ns_view_ids.h
new file mode 100644
index 0000000..d933ad06
--- /dev/null
+++ b/components/remote_cocoa/app_shim/ns_view_ids.h
@@ -0,0 +1,35 @@
+// Copyright 2018 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.
+
+#ifndef COMPONENTS_REMOTE_COCOA_APP_SHIM_NS_VIEW_IDS_H_
+#define COMPONENTS_REMOTE_COCOA_APP_SHIM_NS_VIEW_IDS_H_
+
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "components/remote_cocoa/app_shim/remote_cocoa_app_shim_export.h"
+
+@class NSView;
+
+namespace remote_cocoa {
+
+// Return an NSView given its id. This is to be called in an app shim process.
+NSView* REMOTE_COCOA_APP_SHIM_EXPORT GetNSViewFromId(uint64_t ns_view_id);
+
+// A scoped mapping from |ns_view_id| to |view|. While this object exists,
+// GetNSViewFromId will return |view| when queried with |ns_view_id|. This
+// is to be instantiated in the app shim process.
+class REMOTE_COCOA_APP_SHIM_EXPORT ScopedNSViewIdMapping {
+ public:
+  ScopedNSViewIdMapping(uint64_t ns_view_id, NSView* view);
+  ~ScopedNSViewIdMapping();
+
+ private:
+  const uint64_t ns_view_id_;
+  DISALLOW_COPY_AND_ASSIGN(ScopedNSViewIdMapping);
+};
+
+}  // namespace remote_cocoa
+
+#endif  // COMPONENTS_REMOTE_COCOA_APP_SHIM_NS_VIEW_IDS_H_
diff --git a/ui/base/cocoa/ns_view_ids.mm b/components/remote_cocoa/app_shim/ns_view_ids.mm
similarity index 80%
rename from ui/base/cocoa/ns_view_ids.mm
rename to components/remote_cocoa/app_shim/ns_view_ids.mm
index 3af9ba81..a5bce62 100644
--- a/ui/base/cocoa/ns_view_ids.mm
+++ b/components/remote_cocoa/app_shim/ns_view_ids.mm
@@ -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 "ui/base/cocoa/ns_view_ids.h"
+#include "components/remote_cocoa/app_shim/ns_view_ids.h"
 
 #import <Cocoa/Cocoa.h>
 #include <map>
@@ -11,21 +11,14 @@
 #include "base/logging.h"
 #include "base/no_destructor.h"
 
-namespace ui {
+namespace remote_cocoa {
 
 std::map<uint64_t, NSView*>& GetNSViewIdMap() {
   static base::NoDestructor<std::map<uint64_t, NSView*>> instance;
   return *instance;
 }
 
-// static
-uint64_t NSViewIds::GetNewId() {
-  static uint64_t next_id = 1;
-  return next_id++;
-}
-
-// static
-NSView* NSViewIds::GetNSView(uint64_t ns_view_id) {
+NSView* GetNSViewFromId(uint64_t ns_view_id) {
   auto& view_map = GetNSViewIdMap();
   auto found = view_map.find(ns_view_id);
   if (found == view_map.end())
@@ -46,4 +39,4 @@
   view_map.erase(found);
 }
 
-}  // namespace ui
+}  // namespace remote_cocoa
diff --git a/components/remote_cocoa/app_shim/remote_cocoa_app_shim_export.h b/components/remote_cocoa/app_shim/remote_cocoa_app_shim_export.h
index ccc66f2..355e5b0 100644
--- a/components/remote_cocoa/app_shim/remote_cocoa_app_shim_export.h
+++ b/components/remote_cocoa/app_shim/remote_cocoa_app_shim_export.h
@@ -6,24 +6,14 @@
 #define COMPONENTS_REMOTE_COCOA_APP_SHIM_REMOTE_COCOA_APP_SHIM_EXPORT_H_
 
 // Defines REMOTE_COCOA_APP_SHIM_EXPORT so that functionality implemented by the
-// RemoteMacViews module can be exported to consumers.
+// RemoteCocoa app shim module can be exported to consumers.
 
 #if defined(COMPONENT_BUILD)
-#if defined(WIN32)
-
-#if defined(VIEWS_BRIDGE_MAC_IMPLEMENTATION)
-#define REMOTE_COCOA_APP_SHIM_EXPORT __declspec(dllexport)
-#else
-#define REMOTE_COCOA_APP_SHIM_EXPORT __declspec(dllimport)
-#endif  // defined(VIEWS_BRIDGE_MAC_IMPLEMENTATION)
-
-#else  // defined(WIN32)
-#if defined(VIEWS_BRIDGE_MAC_IMPLEMENTATION)
+#if defined(REMOTE_COCOA_APP_SHIM_IMPLEMENTATION)
 #define REMOTE_COCOA_APP_SHIM_EXPORT __attribute__((visibility("default")))
 #else
 #define REMOTE_COCOA_APP_SHIM_EXPORT
 #endif
-#endif
 
 #else  // defined(COMPONENT_BUILD)
 #define REMOTE_COCOA_APP_SHIM_EXPORT
diff --git a/components/remote_cocoa/browser/BUILD.gn b/components/remote_cocoa/browser/BUILD.gn
new file mode 100644
index 0000000..deaa48e
--- /dev/null
+++ b/components/remote_cocoa/browser/BUILD.gn
@@ -0,0 +1,24 @@
+# Copyright 2019 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.
+
+import("//mojo/public/tools/bindings/mojom.gni")
+
+# This component is for code that is to run in the app shim process.
+component("browser") {
+  assert(is_mac)
+
+  sources = [
+    "ns_view_ids.cc",
+    "ns_view_ids.h",
+    "remote_cocoa_browser_export.h",
+    "window.h",
+    "window.mm",
+  ]
+  defines = [ "REMOTE_COCOA_BROWSER_IMPLEMENTATION" ]
+  deps = [
+    "//base",
+    "//ui/gfx",
+  ]
+  libs = [ "Cocoa.framework" ]
+}
diff --git a/components/remote_cocoa/browser/ns_view_ids.cc b/components/remote_cocoa/browser/ns_view_ids.cc
new file mode 100644
index 0000000..09d14b2
--- /dev/null
+++ b/components/remote_cocoa/browser/ns_view_ids.cc
@@ -0,0 +1,15 @@
+// Copyright 2019 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 "components/remote_cocoa/browser/ns_view_ids.h"
+
+namespace remote_cocoa {
+
+uint64_t GetNewNSViewId() {
+  static uint64_t counter = 0;
+  counter += 1;
+  return counter;
+}
+
+}  // namespace remote_cocoa
diff --git a/components/remote_cocoa/browser/ns_view_ids.h b/components/remote_cocoa/browser/ns_view_ids.h
new file mode 100644
index 0000000..ffdd7723
--- /dev/null
+++ b/components/remote_cocoa/browser/ns_view_ids.h
@@ -0,0 +1,20 @@
+// Copyright 2019 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.
+
+#ifndef COMPONENTS_REMOTE_COCOA_BROWSER_NS_VIEW_IDS_H_
+#define COMPONENTS_REMOTE_COCOA_BROWSER_NS_VIEW_IDS_H_
+
+#include <stdint.h>
+
+#include "components/remote_cocoa/browser/remote_cocoa_browser_export.h"
+
+namespace remote_cocoa {
+
+// Return a new unique is to be used with ScopedNSViewIdMapping and
+// GetNSViewFromId in various app shim processes.
+uint64_t REMOTE_COCOA_BROWSER_EXPORT GetNewNSViewId();
+
+}  // namespace remote_cocoa
+
+#endif  // COMPONENTS_REMOTE_COCOA_BROWSER_NS_VIEW_IDS_H_
diff --git a/components/remote_cocoa/browser/remote_cocoa_browser_export.h b/components/remote_cocoa/browser/remote_cocoa_browser_export.h
new file mode 100644
index 0000000..ff42ffc
--- /dev/null
+++ b/components/remote_cocoa/browser/remote_cocoa_browser_export.h
@@ -0,0 +1,22 @@
+// Copyright 2018 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.
+
+#ifndef COMPONENTS_REMOTE_COCOA_BROWSER_REMOTE_COCOA_BROWSER_EXPORT_H_
+#define COMPONENTS_REMOTE_COCOA_BROWSER_REMOTE_COCOA_BROWSER_EXPORT_H_
+
+// Defines REMOTE_COCOA_BROWSER_EXPORT so that functionality implemented by the
+// RemoteCocoa browser  module can be exported to consumers.
+
+#if defined(COMPONENT_BUILD)
+#if defined(REMOTE_COCOA_BROWSER_IMPLEMENTATION)
+#define REMOTE_COCOA_BROWSER_EXPORT __attribute__((visibility("default")))
+#else
+#define REMOTE_COCOA_BROWSER_EXPORT
+#endif
+
+#else  // defined(COMPONENT_BUILD)
+#define REMOTE_COCOA_BROWSER_EXPORT
+#endif
+
+#endif  // COMPONENTS_REMOTE_COCOA_BROWSER_REMOTE_COCOA_BROWSER_EXPORT_H_
diff --git a/components/remote_cocoa/browser/window.h b/components/remote_cocoa/browser/window.h
new file mode 100644
index 0000000..f3c6f81d
--- /dev/null
+++ b/components/remote_cocoa/browser/window.h
@@ -0,0 +1,25 @@
+// Copyright 2018 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.
+
+#ifndef COMPONENTS_REMOTE_COCOA_BROWSER_WINDOW_H_
+#define COMPONENTS_REMOTE_COCOA_BROWSER_WINDOW_H_
+
+#include "components/remote_cocoa/browser/remote_cocoa_browser_export.h"
+#include "ui/gfx/native_widget_types.h"
+
+namespace remote_cocoa {
+
+// Returns true if the specified NSWindow corresponds to an NSWindow that is
+// being viewed in a remote process.
+bool REMOTE_COCOA_BROWSER_EXPORT IsWindowRemote(gfx::NativeWindow window);
+
+// Create a transparent NSWindow that is in the same position as |window|,
+// but is at the ModalPanel window level, so that it will appear over all
+// other window.
+NSWindow* REMOTE_COCOA_BROWSER_EXPORT
+CreateInProcessTransparentClone(gfx::NativeWindow window);
+
+}  // namespace remote_cocoa
+
+#endif  // COMPONENTS_REMOTE_COCOA_BROWSER_WINDOW_H_
diff --git a/ui/base/cocoa/remote_views_window.mm b/components/remote_cocoa/browser/window.mm
similarity index 71%
rename from ui/base/cocoa/remote_views_window.mm
rename to components/remote_cocoa/browser/window.mm
index c9531ef7..7e22141 100644
--- a/ui/base/cocoa/remote_views_window.mm
+++ b/components/remote_cocoa/browser/window.mm
@@ -2,24 +2,24 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ui/base/cocoa/remote_views_window.h"
+#include "components/remote_cocoa/browser/window.h"
 
 #import <Cocoa/Cocoa.h>
 
 // An NSWindow is using RemoteMacViews if it has no BridgedNativeWidgetImpl.
 // This is the most expedient method of determining if an NSWindow uses
 // RemoteMacViews.
-namespace views {
+namespace remote_cocoa {
 class BridgedNativeWidgetImpl;
-}  // namespace views
+}  // namespace remote_cocoa
 
 @interface NSWindow (Private)
-- (views::BridgedNativeWidgetImpl*)bridgeImpl;
+- (remote_cocoa::BridgedNativeWidgetImpl*)bridgeImpl;
 @end
 
-namespace ui {
+namespace remote_cocoa {
 
-bool IsWindowUsingRemoteViews(gfx::NativeWindow gfx_window) {
+bool IsWindowRemote(gfx::NativeWindow gfx_window) {
   NSWindow* ns_window = gfx_window.GetNativeNSWindow();
   if ([ns_window respondsToSelector:@selector(bridgeImpl)]) {
     if (![ns_window bridgeImpl])
@@ -28,9 +28,8 @@
   return false;
 }
 
-NSWindow* UI_BASE_EXPORT
-CreateTransparentRemoteViewsClone(gfx::NativeWindow remote_window) {
-  DCHECK(IsWindowUsingRemoteViews(remote_window));
+NSWindow* CreateInProcessTransparentClone(gfx::NativeWindow remote_window) {
+  DCHECK(IsWindowRemote(remote_window));
   NSWindow* window = [[NSWindow alloc]
       initWithContentRect:[remote_window.GetNativeNSWindow() frame]
                 styleMask:NSWindowStyleMaskBorderless
@@ -42,4 +41,4 @@
   return window;
 }
 
-}  // namespace ui
+}  // namespace remote_cocoa
diff --git a/components/send_tab_to_self/send_tab_to_self_bridge.cc b/components/send_tab_to_self/send_tab_to_self_bridge.cc
index 76d7bea7..654bdc3 100644
--- a/components/send_tab_to_self/send_tab_to_self_bridge.cc
+++ b/components/send_tab_to_self/send_tab_to_self_bridge.cc
@@ -460,6 +460,11 @@
   return ShouldUpdateTargetDeviceNameToCacheInfoMap();
 }
 
+void SendTabToSelfBridge::SetLocalDeviceNameForTest(
+    const std::string& local_device_name) {
+  local_device_name_ = local_device_name;
+}
+
 void SendTabToSelfBridge::NotifyRemoteSendTabToSelfEntryAdded(
     const std::vector<const SendTabToSelfEntry*>& new_entries) {
   std::vector<const SendTabToSelfEntry*> new_local_entries;
@@ -633,9 +638,12 @@
       break;
     }
 
-    // TODO(crbug.com/957716): Dedupe older versions of this device as well.
-    // Don't include this device.
-    if (device->guid() == change_processor()->TrackedCacheGuid()) {
+    // TODO(crbug.com/966413): Implement a better way to dedupe local devices in
+    // case the user has other devices with the same name.
+    // Don't include this device. Also compare the name as the device can have
+    // different cache guids (e.g. after stopping and re-starting sync).
+    if (device->guid() == change_processor()->TrackedCacheGuid() ||
+        device->client_name() == local_device_name_) {
       continue;
     }
 
diff --git a/components/send_tab_to_self/send_tab_to_self_bridge.h b/components/send_tab_to_self/send_tab_to_self_bridge.h
index b8c0aa57..b3028c10 100644
--- a/components/send_tab_to_self/send_tab_to_self_bridge.h
+++ b/components/send_tab_to_self/send_tab_to_self_bridge.h
@@ -93,6 +93,7 @@
   static std::unique_ptr<syncer::ModelTypeStore> DestroyAndStealStoreForTest(
       std::unique_ptr<SendTabToSelfBridge> bridge);
   bool ShouldUpdateTargetDeviceNameToCacheInfoMapForTest();
+  void SetLocalDeviceNameForTest(const std::string& local_device_name);
 
  private:
   using SendTabToSelfEntries =
diff --git a/components/send_tab_to_self/send_tab_to_self_bridge_unittest.cc b/components/send_tab_to_self/send_tab_to_self_bridge_unittest.cc
index ff11cd87..cacd462 100644
--- a/components/send_tab_to_self/send_tab_to_self_bridge_unittest.cc
+++ b/components/send_tab_to_self/send_tab_to_self_bridge_unittest.cc
@@ -48,6 +48,7 @@
 const char kTitleFormat[] = "title %d";
 const char kDeviceFormat[] = "device %d";
 const char kLocalDeviceCacheGuid[] = "local_device_guid";
+const char kLocalDeviceName[] = "local_device_name";
 
 sync_pb::SendTabToSelfSpecifics CreateSpecifics(
     int suffix,
@@ -775,9 +776,17 @@
 TEST_F(SendTabToSelfBridgeTest,
        GetTargetDeviceNameToCacheInfoMap_NoLocalDevice) {
   InitializeBridge();
+  bridge()->SetLocalDeviceNameForTest(kLocalDeviceName);
 
   syncer::DeviceInfo local_device(
-      kLocalDeviceCacheGuid, "local_device_name", "72", "agent",
+      kLocalDeviceCacheGuid, kLocalDeviceName, "72", "agent",
+      sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "scoped_is",
+      /*last_updated_timestamp=*/clock()->Now(),
+      /*send_tab_to_self_receiving_enabled=*/true);
+  AddTestDevice(&local_device);
+
+  syncer::DeviceInfo other_local_device(
+      "other_local_guid", kLocalDeviceName, "72", "agent",
       sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "scoped_is",
       /*last_updated_timestamp=*/clock()->Now(),
       /*send_tab_to_self_receiving_enabled=*/true);
diff --git a/components/sessions/core/session_service_commands.cc b/components/sessions/core/session_service_commands.cc
index 1a58d05..159accb 100644
--- a/components/sessions/core/session_service_commands.cc
+++ b/components/sessions/core/session_service_commands.cc
@@ -655,6 +655,15 @@
   return true;
 }
 
+template <typename Payload>
+std::unique_ptr<SessionCommand> CreateSessionCommandForPayload(
+    SessionCommand::id_type id,
+    const Payload& payload) {
+  auto command = std::make_unique<SessionCommand>(id, sizeof(payload));
+  memcpy(command->contents(), &payload, sizeof(payload));
+  return command;
+}
+
 }  // namespace
 
 std::unique_ptr<SessionCommand> CreateSetSelectedTabInWindowCommand(
@@ -663,20 +672,14 @@
   SelectedTabInIndexPayload payload = { 0 };
   payload.id = window_id.id();
   payload.index = index;
-  std::unique_ptr<SessionCommand> command = std::make_unique<SessionCommand>(
-      kCommandSetSelectedTabInIndex, sizeof(payload));
-  memcpy(command->contents(), &payload, sizeof(payload));
-  return command;
+  return CreateSessionCommandForPayload(kCommandSetSelectedTabInIndex, payload);
 }
 
 std::unique_ptr<SessionCommand> CreateSetTabWindowCommand(
     const SessionID& window_id,
     const SessionID& tab_id) {
   SessionID::id_type payload[] = { window_id.id(), tab_id.id() };
-  std::unique_ptr<SessionCommand> command =
-      std::make_unique<SessionCommand>(kCommandSetTabWindow, sizeof(payload));
-  memcpy(command->contents(), payload, sizeof(payload));
-  return command;
+  return CreateSessionCommandForPayload(kCommandSetTabWindow, payload);
 }
 
 std::unique_ptr<SessionCommand> CreateSetWindowBoundsCommand(
@@ -690,10 +693,7 @@
   payload.w = bounds.width();
   payload.h = bounds.height();
   payload.show_state = ShowStateToPersistedShowState(show_state);
-  std::unique_ptr<SessionCommand> command = std::make_unique<SessionCommand>(
-      kCommandSetWindowBounds3, sizeof(payload));
-  memcpy(command->contents(), &payload, sizeof(payload));
-  return command;
+  return CreateSessionCommandForPayload(kCommandSetWindowBounds3, payload);
 }
 
 std::unique_ptr<SessionCommand> CreateSetTabIndexInWindowCommand(
@@ -702,10 +702,7 @@
   TabIndexInWindowPayload payload = { 0 };
   payload.id = tab_id.id();
   payload.index = new_index;
-  std::unique_ptr<SessionCommand> command = std::make_unique<SessionCommand>(
-      kCommandSetTabIndexInWindow, sizeof(payload));
-  memcpy(command->contents(), &payload, sizeof(payload));
-  return command;
+  return CreateSessionCommandForPayload(kCommandSetTabIndexInWindow, payload);
 }
 
 std::unique_ptr<SessionCommand> CreateTabClosedCommand(const SessionID tab_id) {
@@ -716,10 +713,7 @@
   memset(&payload, 0, sizeof(payload));
   payload.id = tab_id.id();
   payload.close_time = base::Time::Now().ToInternalValue();
-  std::unique_ptr<SessionCommand> command =
-      std::make_unique<SessionCommand>(kCommandTabClosed, sizeof(payload));
-  memcpy(command->contents(), &payload, sizeof(payload));
-  return command;
+  return CreateSessionCommandForPayload(kCommandTabClosed, payload);
 }
 
 std::unique_ptr<SessionCommand> CreateWindowClosedCommand(
@@ -729,10 +723,7 @@
   memset(&payload, 0, sizeof(payload));
   payload.id = window_id.id();
   payload.close_time = base::Time::Now().ToInternalValue();
-  std::unique_ptr<SessionCommand> command =
-      std::make_unique<SessionCommand>(kCommandWindowClosed, sizeof(payload));
-  memcpy(command->contents(), &payload, sizeof(payload));
-  return command;
+  return CreateSessionCommandForPayload(kCommandWindowClosed, payload);
 }
 
 std::unique_ptr<SessionCommand> CreateSetSelectedNavigationIndexCommand(
@@ -741,10 +732,8 @@
   SelectedNavigationIndexPayload payload = { 0 };
   payload.id = tab_id.id();
   payload.index = index;
-  std::unique_ptr<SessionCommand> command = std::make_unique<SessionCommand>(
-      kCommandSetSelectedNavigationIndex, sizeof(payload));
-  memcpy(command->contents(), &payload, sizeof(payload));
-  return command;
+  return CreateSessionCommandForPayload(kCommandSetSelectedNavigationIndex,
+                                        payload);
 }
 
 std::unique_ptr<SessionCommand> CreateSetWindowTypeCommand(
@@ -753,10 +742,7 @@
   WindowTypePayload payload = { 0 };
   payload.id = window_id.id();
   payload.index = static_cast<int32_t>(type);
-  std::unique_ptr<SessionCommand> command =
-      std::make_unique<SessionCommand>(kCommandSetWindowType, sizeof(payload));
-  memcpy(command->contents(), &payload, sizeof(payload));
-  return command;
+  return CreateSessionCommandForPayload(kCommandSetWindowType, payload);
 }
 
 std::unique_ptr<SessionCommand> CreatePinnedStateCommand(
@@ -765,10 +751,7 @@
   PinnedStatePayload payload = { 0 };
   payload.tab_id = tab_id.id();
   payload.pinned_state = is_pinned;
-  std::unique_ptr<SessionCommand> command =
-      std::make_unique<SessionCommand>(kCommandSetPinnedState, sizeof(payload));
-  memcpy(command->contents(), &payload, sizeof(payload));
-  return command;
+  return CreateSessionCommandForPayload(kCommandSetPinnedState, payload);
 }
 
 std::unique_ptr<SessionCommand> CreateSessionStorageAssociatedCommand(
@@ -777,18 +760,15 @@
   base::Pickle pickle;
   pickle.WriteInt(tab_id.id());
   pickle.WriteString(session_storage_persistent_id);
-  return std::unique_ptr<SessionCommand>(std::make_unique<SessionCommand>(
-      kCommandSessionStorageAssociated, pickle));
+  return std::make_unique<SessionCommand>(kCommandSessionStorageAssociated,
+                                          pickle);
 }
 
 std::unique_ptr<SessionCommand> CreateSetActiveWindowCommand(
     const SessionID& window_id) {
   ActiveWindowPayload payload = 0;
   payload = window_id.id();
-  std::unique_ptr<SessionCommand> command = std::make_unique<SessionCommand>(
-      kCommandSetActiveWindow, sizeof(payload));
-  memcpy(command->contents(), &payload, sizeof(payload));
-  return command;
+  return CreateSessionCommandForPayload(kCommandSetActiveWindow, payload);
 }
 
 std::unique_ptr<SessionCommand> CreateLastActiveTimeCommand(
@@ -797,10 +777,7 @@
   LastActiveTimePayload payload = {0};
   payload.tab_id = tab_id.id();
   payload.last_active_time = last_active_time.ToInternalValue();
-  std::unique_ptr<SessionCommand> command =
-      std::make_unique<SessionCommand>(kCommandLastActiveTime, sizeof(payload));
-  memcpy(command->contents(), &payload, sizeof(payload));
-  return command;
+  return CreateSessionCommandForPayload(kCommandLastActiveTime, payload);
 }
 
 std::unique_ptr<SessionCommand> CreateSetWindowWorkspaceCommand(
@@ -809,9 +786,7 @@
   base::Pickle pickle;
   pickle.WriteInt(window_id.id());
   pickle.WriteString(workspace);
-  std::unique_ptr<SessionCommand> command =
-      std::make_unique<SessionCommand>(kCommandSetWindowWorkspace2, pickle);
-  return command;
+  return std::make_unique<SessionCommand>(kCommandSetWindowWorkspace2, pickle);
 }
 
 std::unique_ptr<SessionCommand> CreateTabNavigationPathPrunedCommand(
@@ -822,10 +797,8 @@
   payload.id = tab_id.id();
   payload.index = index;
   payload.count = count;
-  std::unique_ptr<SessionCommand> command = std::make_unique<SessionCommand>(
-      kCommandTabNavigationPathPruned, sizeof(payload));
-  memcpy(command->contents(), &payload, sizeof(payload));
-  return command;
+  return CreateSessionCommandForPayload(kCommandTabNavigationPathPruned,
+                                        payload);
 }
 
 std::unique_ptr<SessionCommand> CreateUpdateTabNavigationCommand(
diff --git a/components/sync/BUILD.gn b/components/sync/BUILD.gn
index 6a897b39..a8b0637 100644
--- a/components/sync/BUILD.gn
+++ b/components/sync/BUILD.gn
@@ -310,7 +310,13 @@
     "model_impl/sync_metadata_store_change_list.h",
     "model_impl/syncable_service_based_bridge.cc",
     "model_impl/syncable_service_based_bridge.h",
+    "nigori/cryptographer.cc",
+    "nigori/cryptographer.h",
     "nigori/keystore_keys_handler.h",
+    "nigori/nigori.cc",
+    "nigori/nigori.h",
+    "nigori/nigori_key_bag.cc",
+    "nigori/nigori_key_bag.h",
     "nigori/nigori_local_change_processor.cc",
     "nigori/nigori_local_change_processor.h",
     "nigori/nigori_model_type_processor.cc",
@@ -549,14 +555,11 @@
   sources = [
     "base/bind_to_task_runner_unittest.cc",
     "base/cancelation_signal_unittest.cc",
-    "base/cryptographer_unittest.cc",
     "base/data_type_histogram_unittest.cc",
     "base/enum_set_unittest.cc",
     "base/hash_util_unittest.cc",
     "base/immutable_unittest.cc",
     "base/model_type_unittest.cc",
-    "base/nigori_key_bag_unittest.cc",
-    "base/nigori_unittest.cc",
     "base/node_ordinal_unittest.cc",
     "base/ordinal_unittest.cc",
     "base/protobuf_unittest.cc",
@@ -633,8 +636,11 @@
     "model_impl/model_type_store_impl_unittest.cc",
     "model_impl/processor_entity_unittest.cc",
     "model_impl/syncable_service_based_bridge_unittest.cc",
+    "nigori/cryptographer_unittest.cc",
+    "nigori/nigori_key_bag_unittest.cc",
     "nigori/nigori_model_type_processor_unittest.cc",
     "nigori/nigori_sync_bridge_impl_unittest.cc",
+    "nigori/nigori_unittest.cc",
     "protocol/proto_enum_conversions_unittest.cc",
     "protocol/proto_value_conversions_unittest.cc",
     "syncable/change_record_unittest.cc",
diff --git a/components/sync/base/BUILD.gn b/components/sync/base/BUILD.gn
index d493003..c361145 100644
--- a/components/sync/base/BUILD.gn
+++ b/components/sync/base/BUILD.gn
@@ -13,8 +13,6 @@
     "cancelation_observer.h",
     "cancelation_signal.cc",
     "cancelation_signal.h",
-    "cryptographer.cc",
-    "cryptographer.h",
     "data_type_histogram.cc",
     "data_type_histogram.h",
     "encryptor.h",
@@ -34,10 +32,6 @@
     "logging.h",
     "model_type.cc",
     "model_type.h",
-    "nigori.cc",
-    "nigori.h",
-    "nigori_key_bag.cc",
-    "nigori_key_bag.h",
     "node_ordinal.cc",
     "node_ordinal.h",
     "ordinal.h",
diff --git a/components/sync/base/DEPS b/components/sync/base/DEPS
index 7cdbab93..7cddc7e 100644
--- a/components/sync/base/DEPS
+++ b/components/sync/base/DEPS
@@ -6,7 +6,6 @@
   "+components/reading_list/features",
   "+components/sync/protocol",
   "+components/sync_preferences",
-  "+crypto",
   "+google/cacheinvalidation",
   "+third_party/zlib",  # For UniquePosition compression
   "+net",
diff --git a/components/sync/driver/DEPS b/components/sync/driver/DEPS
index ad4c760..cc24f7a7 100644
--- a/components/sync/driver/DEPS
+++ b/components/sync/driver/DEPS
@@ -18,6 +18,7 @@
   "+components/sync/js",
   "+components/sync/model",
   "+components/sync/model_impl",
+  "+components/sync/nigori",
   "+components/sync/protocol",
   "+components/sync/syncable",
   "+components/sync/test",
diff --git a/components/sync/driver/sync_service_crypto.cc b/components/sync/driver/sync_service_crypto.cc
index ac0d9d2..4c0e7b8 100644
--- a/components/sync/driver/sync_service_crypto.cc
+++ b/components/sync/driver/sync_service_crypto.cc
@@ -11,11 +11,11 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/sequenced_task_runner.h"
 #include "base/threading/sequenced_task_runner_handle.h"
-#include "components/sync/base/nigori.h"
 #include "components/sync/base/sync_prefs.h"
 #include "components/sync/driver/sync_driver_switches.h"
 #include "components/sync/driver/sync_service.h"
 #include "components/sync/engine/sync_string_conversions.h"
+#include "components/sync/nigori/nigori.h"
 
 namespace syncer {
 
diff --git a/components/sync/engine/DEPS b/components/sync/engine/DEPS
index 120b16f..07bbd4d 100644
--- a/components/sync/engine/DEPS
+++ b/components/sync/engine/DEPS
@@ -2,6 +2,7 @@
   "+components/sync/base",
   "+components/sync/engine_impl",
   "+components/sync/model",
+  "+components/sync/nigori",
   "+components/sync/protocol",
   "+components/sync/syncable",
   "+components/sync/test",
diff --git a/components/sync/engine/engine_util.cc b/components/sync/engine/engine_util.cc
index a0e8a16..2c3df3c0 100644
--- a/components/sync/engine/engine_util.cc
+++ b/components/sync/engine/engine_util.cc
@@ -10,7 +10,7 @@
 
 #include "base/logging.h"
 #include "base/stl_util.h"
-#include "components/sync/base/cryptographer.h"
+#include "components/sync/nigori/cryptographer.h"
 #include "components/sync/protocol/password_specifics.pb.h"
 #include "components/sync/protocol/sync.pb.h"
 
diff --git a/components/sync/engine/sync_encryption_handler.h b/components/sync/engine/sync_encryption_handler.h
index df23cb9..6681818 100644
--- a/components/sync/engine/sync_encryption_handler.h
+++ b/components/sync/engine/sync_encryption_handler.h
@@ -9,8 +9,8 @@
 
 #include "base/time/time.h"
 #include "components/sync/base/model_type.h"
-#include "components/sync/base/nigori.h"
 #include "components/sync/base/passphrase_enums.h"
+#include "components/sync/nigori/nigori.h"
 #include "components/sync/protocol/sync.pb.h"
 
 namespace syncer {
diff --git a/components/sync/engine_impl/apply_control_data_updates.cc b/components/sync/engine_impl/apply_control_data_updates.cc
index faa0589..7b63249 100644
--- a/components/sync/engine_impl/apply_control_data_updates.cc
+++ b/components/sync/engine_impl/apply_control_data_updates.cc
@@ -9,10 +9,10 @@
 #include <vector>
 
 #include "base/metrics/histogram_macros.h"
-#include "components/sync/base/cryptographer.h"
 #include "components/sync/engine_impl/conflict_resolver.h"
 #include "components/sync/engine_impl/conflict_util.h"
 #include "components/sync/engine_impl/syncer_util.h"
+#include "components/sync/nigori/cryptographer.h"
 #include "components/sync/syncable/directory.h"
 #include "components/sync/syncable/mutable_entry.h"
 #include "components/sync/syncable/nigori_handler.h"
diff --git a/components/sync/engine_impl/apply_control_data_updates_unittest.cc b/components/sync/engine_impl/apply_control_data_updates_unittest.cc
index b7b5629..eca1fa5 100644
--- a/components/sync/engine_impl/apply_control_data_updates_unittest.cc
+++ b/components/sync/engine_impl/apply_control_data_updates_unittest.cc
@@ -15,10 +15,10 @@
 #include "base/macros.h"
 #include "base/strings/stringprintf.h"
 #include "base/test/scoped_task_environment.h"
-#include "components/sync/base/cryptographer.h"
 #include "components/sync/engine_impl/syncer.h"
 #include "components/sync/engine_impl/syncer_util.h"
 #include "components/sync/engine_impl/test_entry_factory.h"
+#include "components/sync/nigori/cryptographer.h"
 #include "components/sync/protocol/nigori_specifics.pb.h"
 #include "components/sync/syncable/directory.h"
 #include "components/sync/syncable/mutable_entry.h"
diff --git a/components/sync/engine_impl/conflict_resolver.cc b/components/sync/engine_impl/conflict_resolver.cc
index 8456f206..f64c178 100644
--- a/components/sync/engine_impl/conflict_resolver.cc
+++ b/components/sync/engine_impl/conflict_resolver.cc
@@ -7,11 +7,11 @@
 #include <string>
 
 #include "base/metrics/histogram_macros.h"
-#include "components/sync/base/cryptographer.h"
 #include "components/sync/engine/cycle/update_counters.h"
 #include "components/sync/engine_impl/conflict_util.h"
 #include "components/sync/engine_impl/cycle/status_controller.h"
 #include "components/sync/engine_impl/syncer_util.h"
+#include "components/sync/nigori/cryptographer.h"
 #include "components/sync/syncable/directory.h"
 #include "components/sync/syncable/mutable_entry.h"
 #include "components/sync/syncable/syncable_write_transaction.h"
diff --git a/components/sync/engine_impl/debug_info_event_listener.cc b/components/sync/engine_impl/debug_info_event_listener.cc
index 579fbaf2..ff23ff27 100644
--- a/components/sync/engine_impl/debug_info_event_listener.cc
+++ b/components/sync/engine_impl/debug_info_event_listener.cc
@@ -6,7 +6,7 @@
 
 #include <stddef.h>
 
-#include "components/sync/base/cryptographer.h"
+#include "components/sync/nigori/cryptographer.h"
 
 namespace syncer {
 
diff --git a/components/sync/engine_impl/get_commit_ids.cc b/components/sync/engine_impl/get_commit_ids.cc
index 5442929..47aa2e82 100644
--- a/components/sync/engine_impl/get_commit_ids.cc
+++ b/components/sync/engine_impl/get_commit_ids.cc
@@ -8,8 +8,8 @@
 
 #include "base/macros.h"
 #include "base/stl_util.h"
-#include "components/sync/base/cryptographer.h"
 #include "components/sync/engine_impl/syncer_util.h"
+#include "components/sync/nigori/cryptographer.h"
 #include "components/sync/syncable/entry.h"
 #include "components/sync/syncable/nigori_handler.h"
 #include "components/sync/syncable/nigori_util.h"
diff --git a/components/sync/engine_impl/js_sync_encryption_handler_observer.cc b/components/sync/engine_impl/js_sync_encryption_handler_observer.cc
index b675a565e..005f27c3 100644
--- a/components/sync/engine_impl/js_sync_encryption_handler_observer.cc
+++ b/components/sync/engine_impl/js_sync_encryption_handler_observer.cc
@@ -10,12 +10,12 @@
 #include "base/logging.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
-#include "components/sync/base/cryptographer.h"
 #include "components/sync/base/model_type.h"
 #include "components/sync/base/time.h"
 #include "components/sync/engine/sync_string_conversions.h"
 #include "components/sync/js/js_event_details.h"
 #include "components/sync/js/js_event_handler.h"
+#include "components/sync/nigori/cryptographer.h"
 
 namespace syncer {
 
diff --git a/components/sync/engine_impl/js_sync_encryption_handler_observer_unittest.cc b/components/sync/engine_impl/js_sync_encryption_handler_observer_unittest.cc
index e44cf33..c67d9718 100644
--- a/components/sync/engine_impl/js_sync_encryption_handler_observer_unittest.cc
+++ b/components/sync/engine_impl/js_sync_encryption_handler_observer_unittest.cc
@@ -11,7 +11,6 @@
 #include "base/run_loop.h"
 #include "base/test/scoped_task_environment.h"
 #include "base/values.h"
-#include "components/sync/base/cryptographer.h"
 #include "components/sync/base/fake_encryptor.h"
 #include "components/sync/base/model_type.h"
 #include "components/sync/base/passphrase_enums.h"
@@ -19,6 +18,7 @@
 #include "components/sync/engine/sync_string_conversions.h"
 #include "components/sync/js/js_event_details.h"
 #include "components/sync/js/js_test_util.h"
+#include "components/sync/nigori/cryptographer.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace syncer {
diff --git a/components/sync/engine_impl/model_type_registry.cc b/components/sync/engine_impl/model_type_registry.cc
index ee4b09cf..4e4717d 100644
--- a/components/sync/engine_impl/model_type_registry.cc
+++ b/components/sync/engine_impl/model_type_registry.cc
@@ -13,7 +13,6 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/observer_list.h"
 #include "base/threading/sequenced_task_runner_handle.h"
-#include "components/sync/base/cryptographer.h"
 #include "components/sync/engine/commit_queue.h"
 #include "components/sync/engine/data_type_activation_response.h"
 #include "components/sync/engine/model_type_processor.h"
@@ -22,6 +21,7 @@
 #include "components/sync/engine_impl/directory_commit_contributor.h"
 #include "components/sync/engine_impl/directory_update_handler.h"
 #include "components/sync/engine_impl/model_type_worker.h"
+#include "components/sync/nigori/cryptographer.h"
 #include "components/sync/nigori/keystore_keys_handler.h"
 #include "components/sync/syncable/read_transaction.h"
 #include "components/sync/syncable/syncable_base_transaction.h"
diff --git a/components/sync/engine_impl/model_type_worker.h b/components/sync/engine_impl/model_type_worker.h
index 3fd9f73..f09eab8 100644
--- a/components/sync/engine_impl/model_type_worker.h
+++ b/components/sync/engine_impl/model_type_worker.h
@@ -17,7 +17,6 @@
 #include "base/sequence_checker.h"
 #include "base/synchronization/waitable_event.h"
 #include "components/sync/base/cancelation_observer.h"
-#include "components/sync/base/cryptographer.h"
 #include "components/sync/base/model_type.h"
 #include "components/sync/base/passphrase_enums.h"
 #include "components/sync/engine/commit_queue.h"
@@ -27,6 +26,7 @@
 #include "components/sync/engine_impl/cycle/data_type_debug_info_emitter.h"
 #include "components/sync/engine_impl/nudge_handler.h"
 #include "components/sync/engine_impl/update_handler.h"
+#include "components/sync/nigori/cryptographer.h"
 #include "components/sync/protocol/model_type_state.pb.h"
 #include "components/sync/protocol/sync.pb.h"
 
diff --git a/components/sync/engine_impl/non_blocking_type_commit_contribution_unittest.cc b/components/sync/engine_impl/non_blocking_type_commit_contribution_unittest.cc
index f0552ea1..ebd8d2f6 100644
--- a/components/sync/engine_impl/non_blocking_type_commit_contribution_unittest.cc
+++ b/components/sync/engine_impl/non_blocking_type_commit_contribution_unittest.cc
@@ -10,11 +10,11 @@
 
 #include "base/base64.h"
 #include "base/hash/sha1.h"
-#include "components/sync/base/cryptographer.h"
 #include "components/sync/base/fake_encryptor.h"
 #include "components/sync/base/hash_util.h"
 #include "components/sync/base/model_type.h"
 #include "components/sync/base/unique_position.h"
+#include "components/sync/nigori/cryptographer.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace syncer {
diff --git a/components/sync/engine_impl/process_updates_util.cc b/components/sync/engine_impl/process_updates_util.cc
index b292460c..938f9a5c 100644
--- a/components/sync/engine_impl/process_updates_util.cc
+++ b/components/sync/engine_impl/process_updates_util.cc
@@ -10,12 +10,12 @@
 
 #include "base/location.h"
 #include "base/metrics/histogram_macros.h"
-#include "components/sync/base/cryptographer.h"
 #include "components/sync/base/data_type_histogram.h"
 #include "components/sync/engine/cycle/update_counters.h"
 #include "components/sync/engine_impl/syncer_proto_util.h"
 #include "components/sync/engine_impl/syncer_types.h"
 #include "components/sync/engine_impl/syncer_util.h"
+#include "components/sync/nigori/cryptographer.h"
 #include "components/sync/syncable/directory.h"
 #include "components/sync/syncable/model_neutral_mutable_entry.h"
 #include "components/sync/syncable/syncable_model_neutral_write_transaction.h"
diff --git a/components/sync/engine_impl/sync_encryption_handler_impl.h b/components/sync/engine_impl/sync_encryption_handler_impl.h
index c18c0e6..35e6a31 100644
--- a/components/sync/engine_impl/sync_encryption_handler_impl.h
+++ b/components/sync/engine_impl/sync_encryption_handler_impl.h
@@ -17,8 +17,8 @@
 #include "base/optional.h"
 #include "base/sequence_checker.h"
 #include "base/time/time.h"
-#include "components/sync/base/cryptographer.h"
 #include "components/sync/engine/sync_encryption_handler.h"
+#include "components/sync/nigori/cryptographer.h"
 #include "components/sync/nigori/keystore_keys_handler.h"
 #include "components/sync/syncable/nigori_handler.h"
 
diff --git a/components/sync/engine_impl/sync_manager_impl.cc b/components/sync/engine_impl/sync_manager_impl.cc
index 6116591..4d43b0d 100644
--- a/components/sync/engine_impl/sync_manager_impl.cc
+++ b/components/sync/engine_impl/sync_manager_impl.cc
@@ -21,7 +21,6 @@
 #include "components/sync/base/cancelation_signal.h"
 #include "components/sync/base/invalidation_interface.h"
 #include "components/sync/base/model_type.h"
-#include "components/sync/base/nigori.h"
 #include "components/sync/engine/configure_reason.h"
 #include "components/sync/engine/engine_components_factory.h"
 #include "components/sync/engine/engine_util.h"
@@ -36,6 +35,7 @@
 #include "components/sync/engine_impl/sync_scheduler.h"
 #include "components/sync/engine_impl/syncer_types.h"
 #include "components/sync/engine_impl/uss_migrator.h"
+#include "components/sync/nigori/nigori.h"
 #include "components/sync/nigori/nigori_model_type_processor.h"
 #include "components/sync/nigori/nigori_sync_bridge_impl.h"
 #include "components/sync/protocol/sync.pb.h"
diff --git a/components/sync/engine_impl/sync_manager_impl.h b/components/sync/engine_impl/sync_manager_impl.h
index f1081ad..e9b9785 100644
--- a/components/sync/engine_impl/sync_manager_impl.h
+++ b/components/sync/engine_impl/sync_manager_impl.h
@@ -16,7 +16,6 @@
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/sequence_checker.h"
-#include "components/sync/base/cryptographer.h"
 #include "components/sync/base/time.h"
 #include "components/sync/engine/sync_manager.h"
 #include "components/sync/engine_impl/all_status.h"
@@ -29,6 +28,7 @@
 #include "components/sync/engine_impl/nudge_handler.h"
 #include "components/sync/engine_impl/sync_engine_event_listener.h"
 #include "components/sync/js/js_backend.h"
+#include "components/sync/nigori/cryptographer.h"
 #include "components/sync/syncable/change_reorder_buffer.h"
 #include "components/sync/syncable/directory_change_delegate.h"
 #include "components/sync/syncable/user_share.h"
diff --git a/components/sync/engine_impl/syncer_unittest.cc b/components/sync/engine_impl/syncer_unittest.cc
index 31cf064..92dbd9f 100644
--- a/components/sync/engine_impl/syncer_unittest.cc
+++ b/components/sync/engine_impl/syncer_unittest.cc
@@ -26,7 +26,6 @@
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "components/sync/base/cancelation_signal.h"
-#include "components/sync/base/cryptographer.h"
 #include "components/sync/base/extensions_activity.h"
 #include "components/sync/base/fake_encryptor.h"
 #include "components/sync/base/time.h"
@@ -41,6 +40,7 @@
 #include "components/sync/engine_impl/net/server_connection_manager.h"
 #include "components/sync/engine_impl/sync_scheduler_impl.h"
 #include "components/sync/engine_impl/syncer_proto_util.h"
+#include "components/sync/nigori/cryptographer.h"
 #include "components/sync/protocol/bookmark_specifics.pb.h"
 #include "components/sync/protocol/nigori_specifics.pb.h"
 #include "components/sync/protocol/preference_specifics.pb.h"
diff --git a/components/sync/engine_impl/syncer_util.cc b/components/sync/engine_impl/syncer_util.cc
index 53d920b..c99d4e7 100644
--- a/components/sync/engine_impl/syncer_util.cc
+++ b/components/sync/engine_impl/syncer_util.cc
@@ -11,13 +11,13 @@
 #include "base/metrics/histogram.h"
 #include "base/rand_util.h"
 #include "base/strings/string_number_conversions.h"
-#include "components/sync/base/cryptographer.h"
 #include "components/sync/base/hash_util.h"
 #include "components/sync/base/model_type.h"
 #include "components/sync/base/time.h"
 #include "components/sync/base/unique_position.h"
 #include "components/sync/engine_impl/conflict_resolver.h"
 #include "components/sync/engine_impl/syncer_proto_util.h"
+#include "components/sync/nigori/cryptographer.h"
 #include "components/sync/protocol/bookmark_specifics.pb.h"
 #include "components/sync/protocol/password_specifics.pb.h"
 #include "components/sync/protocol/sync.pb.h"
diff --git a/components/sync/nigori/DEPS b/components/sync/nigori/DEPS
index b5d098f..c2ee8b4 100644
--- a/components/sync/nigori/DEPS
+++ b/components/sync/nigori/DEPS
@@ -4,4 +4,5 @@
   "+components/sync/model",
   "+components/sync/model_impl",
   "+components/sync/protocol",
+  "+crypto",
 ]
diff --git a/components/sync/base/cryptographer.cc b/components/sync/nigori/cryptographer.cc
similarity index 99%
rename from components/sync/base/cryptographer.cc
rename to components/sync/nigori/cryptographer.cc
index b0badd0..a14978f3b 100644
--- a/components/sync/base/cryptographer.cc
+++ b/components/sync/nigori/cryptographer.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 "components/sync/base/cryptographer.h"
+#include "components/sync/nigori/cryptographer.h"
 
 #include <stddef.h>
 
diff --git a/components/sync/base/cryptographer.h b/components/sync/nigori/cryptographer.h
similarity index 96%
rename from components/sync/base/cryptographer.h
rename to components/sync/nigori/cryptographer.h
index 40a5ab8..2606892 100644
--- a/components/sync/base/cryptographer.h
+++ b/components/sync/nigori/cryptographer.h
@@ -2,22 +2,22 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef COMPONENTS_SYNC_BASE_CRYPTOGRAPHER_H_
-#define COMPONENTS_SYNC_BASE_CRYPTOGRAPHER_H_
+#ifndef COMPONENTS_SYNC_NIGORI_CRYPTOGRAPHER_H_
+#define COMPONENTS_SYNC_NIGORI_CRYPTOGRAPHER_H_
 
 #include <map>
 #include <memory>
 #include <string>
 
 #include "base/macros.h"
-#include "components/sync/base/nigori.h"
-#include "components/sync/base/nigori_key_bag.h"
 #include "components/sync/base/passphrase_enums.h"
+#include "components/sync/nigori/nigori.h"
+#include "components/sync/nigori/nigori_key_bag.h"
 #include "components/sync/protocol/encryption.pb.h"
 
 namespace sync_pb {
 class NigoriKeyBag;
-}
+}  // namespace sync_pb
 
 namespace syncer {
 
@@ -217,4 +217,4 @@
 
 }  // namespace syncer
 
-#endif  // COMPONENTS_SYNC_BASE_CRYPTOGRAPHER_H_
+#endif  // COMPONENTS_SYNC_NIGORI_CRYPTOGRAPHER_H_
diff --git a/components/sync/base/cryptographer_unittest.cc b/components/sync/nigori/cryptographer_unittest.cc
similarity index 99%
rename from components/sync/base/cryptographer_unittest.cc
rename to components/sync/nigori/cryptographer_unittest.cc
index e309207..6d3e4ba 100644
--- a/components/sync/base/cryptographer_unittest.cc
+++ b/components/sync/nigori/cryptographer_unittest.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 "components/sync/base/cryptographer.h"
+#include "components/sync/nigori/cryptographer.h"
 
 #include "base/strings/string_util.h"
 #include "components/sync/base/fake_encryptor.h"
diff --git a/components/sync/base/nigori.cc b/components/sync/nigori/nigori.cc
similarity index 98%
rename from components/sync/base/nigori.cc
rename to components/sync/nigori/nigori.cc
index eee629f..337588f 100644
--- a/components/sync/base/nigori.cc
+++ b/components/sync/nigori/nigori.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 "components/sync/base/nigori.h"
+#include "components/sync/nigori/nigori.h"
 
 #include <stdint.h>
 
@@ -24,8 +24,8 @@
 #include "crypto/random.h"
 #include "crypto/symmetric_key.h"
 
-using base::Base64Encode;
 using base::Base64Decode;
+using base::Base64Encode;
 using crypto::HMAC;
 using crypto::SymmetricKey;
 
@@ -88,8 +88,7 @@
 
 KeyDerivationParams::KeyDerivationParams(KeyDerivationMethod method,
                                          const std::string& scrypt_salt)
-    : method_(method),
-      scrypt_salt_(scrypt_salt) {}
+    : method_(method), scrypt_salt_(scrypt_salt) {}
 
 KeyDerivationParams::KeyDerivationParams(const KeyDerivationParams& other) =
     default;
@@ -99,8 +98,7 @@
     const KeyDerivationParams& other) = default;
 
 bool KeyDerivationParams::operator==(const KeyDerivationParams& other) const {
-  return method_ == other.method_ &&
-         scrypt_salt_ == other.scrypt_salt_;
+  return method_ == other.method_ && scrypt_salt_ == other.scrypt_salt_;
 }
 
 bool KeyDerivationParams::operator!=(const KeyDerivationParams& other) const {
diff --git a/components/sync/base/nigori.h b/components/sync/nigori/nigori.h
similarity index 96%
rename from components/sync/base/nigori.h
rename to components/sync/nigori/nigori.h
index 619ab41..94e9868 100644
--- a/components/sync/base/nigori.h
+++ b/components/sync/nigori/nigori.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 COMPONENTS_SYNC_BASE_NIGORI_H_
-#define COMPONENTS_SYNC_BASE_NIGORI_H_
+#ifndef COMPONENTS_SYNC_NIGORI_NIGORI_H_
+#define COMPONENTS_SYNC_NIGORI_NIGORI_H_
 
 #include <stddef.h>
 
@@ -131,4 +131,4 @@
 
 }  // namespace syncer
 
-#endif  // COMPONENTS_SYNC_BASE_NIGORI_H_
+#endif  // COMPONENTS_SYNC_NIGORI_NIGORI_H_
diff --git a/components/sync/base/nigori_key_bag.cc b/components/sync/nigori/nigori_key_bag.cc
similarity index 97%
rename from components/sync/base/nigori_key_bag.cc
rename to components/sync/nigori/nigori_key_bag.cc
index f394eb6..acb11d69e 100644
--- a/components/sync/base/nigori_key_bag.cc
+++ b/components/sync/nigori/nigori_key_bag.cc
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/sync/base/nigori_key_bag.h"
+#include "components/sync/nigori/nigori_key_bag.h"
 
 #include <utility>
 
 #include "base/logging.h"
-#include "components/sync/base/nigori.h"
+#include "components/sync/nigori/nigori.h"
 #include "components/sync/protocol/nigori_specifics.pb.h"
 
 namespace syncer {
diff --git a/components/sync/base/nigori_key_bag.h b/components/sync/nigori/nigori_key_bag.h
similarity index 92%
rename from components/sync/base/nigori_key_bag.h
rename to components/sync/nigori/nigori_key_bag.h
index 43b276d..eee62e7 100644
--- a/components/sync/base/nigori_key_bag.h
+++ b/components/sync/nigori/nigori_key_bag.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 COMPONENTS_SYNC_BASE_NIGORI_KEY_BAG_H_
-#define COMPONENTS_SYNC_BASE_NIGORI_KEY_BAG_H_
+#ifndef COMPONENTS_SYNC_NIGORI_NIGORI_KEY_BAG_H_
+#define COMPONENTS_SYNC_NIGORI_NIGORI_KEY_BAG_H_
 
 #include <map>
 #include <memory>
@@ -70,4 +70,4 @@
 
 }  // namespace syncer
 
-#endif  // COMPONENTS_SYNC_BASE_NIGORI_KEY_BAG_H_
+#endif  // COMPONENTS_SYNC_NIGORI_NIGORI_KEY_BAG_H_
diff --git a/components/sync/base/nigori_key_bag_unittest.cc b/components/sync/nigori/nigori_key_bag_unittest.cc
similarity index 97%
rename from components/sync/base/nigori_key_bag_unittest.cc
rename to components/sync/nigori/nigori_key_bag_unittest.cc
index b563d5b..afd06c5 100644
--- a/components/sync/base/nigori_key_bag_unittest.cc
+++ b/components/sync/nigori/nigori_key_bag_unittest.cc
@@ -2,9 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/sync/base/nigori_key_bag.h"
+#include "components/sync/nigori/nigori_key_bag.h"
 
-#include "components/sync/base/nigori.h"
+#include "components/sync/nigori/nigori.h"
 #include "components/sync/protocol/nigori_specifics.pb.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/components/sync/nigori/nigori_sync_bridge_impl.cc b/components/sync/nigori/nigori_sync_bridge_impl.cc
index 9b789db..400a1eb3 100644
--- a/components/sync/nigori/nigori_sync_bridge_impl.cc
+++ b/components/sync/nigori/nigori_sync_bridge_impl.cc
@@ -8,10 +8,10 @@
 
 #include "base/base64.h"
 #include "base/location.h"
-#include "components/sync/base/nigori.h"
 #include "components/sync/base/passphrase_enums.h"
 #include "components/sync/base/time.h"
 #include "components/sync/model/entity_data.h"
+#include "components/sync/nigori/nigori.h"
 #include "components/sync/protocol/encryption.pb.h"
 #include "components/sync/protocol/nigori_specifics.pb.h"
 
diff --git a/components/sync/nigori/nigori_sync_bridge_impl.h b/components/sync/nigori/nigori_sync_bridge_impl.h
index f5a79981..fcf14f1 100644
--- a/components/sync/nigori/nigori_sync_bridge_impl.h
+++ b/components/sync/nigori/nigori_sync_bridge_impl.h
@@ -14,10 +14,10 @@
 #include "base/optional.h"
 #include "base/sequence_checker.h"
 #include "base/time/time.h"
-#include "components/sync/base/cryptographer.h"
 #include "components/sync/engine/sync_encryption_handler.h"
 #include "components/sync/model/conflict_resolution.h"
 #include "components/sync/model/model_error.h"
+#include "components/sync/nigori/cryptographer.h"
 #include "components/sync/nigori/keystore_keys_handler.h"
 #include "components/sync/nigori/nigori_local_change_processor.h"
 #include "components/sync/nigori/nigori_sync_bridge.h"
diff --git a/components/sync/base/nigori_unittest.cc b/components/sync/nigori/nigori_unittest.cc
similarity index 99%
rename from components/sync/base/nigori_unittest.cc
rename to components/sync/nigori/nigori_unittest.cc
index d90a6e68..a191ce6 100644
--- a/components/sync/base/nigori_unittest.cc
+++ b/components/sync/nigori/nigori_unittest.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 "components/sync/base/nigori.h"
+#include "components/sync/nigori/nigori.h"
 
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
diff --git a/components/sync/syncable/DEPS b/components/sync/syncable/DEPS
index 93eb3c8..5f67a40 100644
--- a/components/sync/syncable/DEPS
+++ b/components/sync/syncable/DEPS
@@ -2,6 +2,7 @@
   "+components/sync/base",
   "+components/sync/engine",
   "+components/sync/model",
+  "+components/sync/nigori",
   "+components/sync/protocol",
   "+components/sync/test",
   "+net/base/escape.h",
diff --git a/components/sync/syncable/base_transaction.h b/components/sync/syncable/base_transaction.h
index 2fbc103..9ebad818 100644
--- a/components/sync/syncable/base_transaction.h
+++ b/components/sync/syncable/base_transaction.h
@@ -6,8 +6,8 @@
 #define COMPONENTS_SYNC_SYNCABLE_BASE_TRANSACTION_H_
 
 #include "base/macros.h"
-#include "components/sync/base/cryptographer.h"
 #include "components/sync/base/model_type.h"
+#include "components/sync/nigori/cryptographer.h"
 #include "components/sync/syncable/user_share.h"
 
 namespace syncer {
diff --git a/components/sync/syncable/entry_kernel.cc b/components/sync/syncable/entry_kernel.cc
index 05d73a2..8bccff8 100644
--- a/components/sync/syncable/entry_kernel.cc
+++ b/components/sync/syncable/entry_kernel.cc
@@ -9,7 +9,7 @@
 #include "base/json/string_escape.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/trace_event/memory_usage_estimator.h"
-#include "components/sync/base/cryptographer.h"
+#include "components/sync/nigori/cryptographer.h"
 #include "components/sync/protocol/proto_memory_estimations.h"
 #include "components/sync/protocol/proto_value_conversions.h"
 #include "components/sync/syncable/syncable_columns.h"
diff --git a/components/sync/syncable/nigori_util.cc b/components/sync/syncable/nigori_util.cc
index 215c635..e697143b 100644
--- a/components/sync/syncable/nigori_util.cc
+++ b/components/sync/syncable/nigori_util.cc
@@ -14,8 +14,8 @@
 #include "base/containers/queue.h"
 #include "base/json/json_writer.h"
 #include "base/metrics/histogram_macros.h"
-#include "components/sync/base/cryptographer.h"
 #include "components/sync/base/passphrase_enums.h"
+#include "components/sync/nigori/cryptographer.h"
 #include "components/sync/syncable/directory.h"
 #include "components/sync/syncable/entry.h"
 #include "components/sync/syncable/mutable_entry.h"
diff --git a/components/sync/syncable/nigori_util_unittest.cc b/components/sync/syncable/nigori_util_unittest.cc
index e354678..c27dd69 100644
--- a/components/sync/syncable/nigori_util_unittest.cc
+++ b/components/sync/syncable/nigori_util_unittest.cc
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "components/sync/base/cryptographer.h"
+#include "components/sync/syncable/nigori_util.h"
+#include "components/sync/nigori/cryptographer.h"
 #include "components/sync/protocol/bookmark_specifics.pb.h"
 #include "components/sync/protocol/sync.pb.h"
-#include "components/sync/syncable/nigori_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace syncer {
diff --git a/components/sync/syncable/write_node.cc b/components/sync/syncable/write_node.cc
index 82b83786..9d48dff0 100644
--- a/components/sync/syncable/write_node.cc
+++ b/components/sync/syncable/write_node.cc
@@ -9,10 +9,10 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
-#include "components/sync/base/cryptographer.h"
 #include "components/sync/base/hash_util.h"
 #include "components/sync/base/passphrase_enums.h"
 #include "components/sync/engine/engine_util.h"
+#include "components/sync/nigori/cryptographer.h"
 #include "components/sync/protocol/bookmark_specifics.pb.h"
 #include "components/sync/protocol/typed_url_specifics.pb.h"
 #include "components/sync/syncable/base_transaction.h"
diff --git a/components/sync/test/fake_sync_encryption_handler.h b/components/sync/test/fake_sync_encryption_handler.h
index 10a5694..002b0654 100644
--- a/components/sync/test/fake_sync_encryption_handler.h
+++ b/components/sync/test/fake_sync_encryption_handler.h
@@ -11,9 +11,9 @@
 #include "base/compiler_specific.h"
 #include "base/observer_list.h"
 #include "base/time/time.h"
-#include "components/sync/base/cryptographer.h"
 #include "components/sync/base/fake_encryptor.h"
 #include "components/sync/engine/sync_encryption_handler.h"
+#include "components/sync/nigori/cryptographer.h"
 #include "components/sync/nigori/keystore_keys_handler.h"
 #include "components/sync/syncable/nigori_handler.h"
 
diff --git a/components/sync_bookmarks/bookmark_model_associator.cc b/components/sync_bookmarks/bookmark_model_associator.cc
index 8c09407..06c1a31 100644
--- a/components/sync_bookmarks/bookmark_model_associator.cc
+++ b/components/sync_bookmarks/bookmark_model_associator.cc
@@ -18,11 +18,11 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/bookmarks/browser/bookmark_client.h"
 #include "components/bookmarks/browser/bookmark_model.h"
-#include "components/sync/base/cryptographer.h"
 #include "components/sync/base/data_type_histogram.h"
 #include "components/sync/engine/engine_util.h"
 #include "components/sync/model/sync_error.h"
 #include "components/sync/model/sync_merge_result.h"
+#include "components/sync/nigori/cryptographer.h"
 #include "components/sync/syncable/delete_journal.h"
 #include "components/sync/syncable/entry.h"
 #include "components/sync/syncable/read_node.h"
diff --git a/components/translate/ios/browser/BUILD.gn b/components/translate/ios/browser/BUILD.gn
index 15f6c2d7..97fb439 100644
--- a/components/translate/ios/browser/BUILD.gn
+++ b/components/translate/ios/browser/BUILD.gn
@@ -30,7 +30,11 @@
     "//components/translate/core/common",
     "//components/translate/core/language_detection",
     "//ios/chrome/browser/metrics:ukm_url_recorder",
-    "//ios/web",
+    "//ios/web/public",
+    "//ios/web/public/deprecated",
+    "//net",
+    "//net/traffic_annotation:traffic_annotation",
+    "//services/network/public/cpp:cpp_base",
     "//ui/base",
     "//url",
   ]
@@ -62,8 +66,8 @@
     "//components/resources",
     "//components/translate/core/browser",
     "//components/translate/core/common",
+    "//ios/web/public/deprecated:test_doubles",
     "//ios/web/public/test",
-    "//ios/web/public/test/fakes",
     "//net:net",
     "//testing/gtest",
     "//third_party/ocmock",
diff --git a/components/translate/ios/browser/ios_translate_driver.mm b/components/translate/ios/browser/ios_translate_driver.mm
index 57f381a..40aa13a1e 100644
--- a/components/translate/ios/browser/ios_translate_driver.mm
+++ b/components/translate/ios/browser/ios_translate_driver.mm
@@ -20,10 +20,10 @@
 #import "components/translate/ios/browser/translate_controller.h"
 #include "ios/chrome/browser/metrics/ukm_url_recorder.h"
 #include "ios/web/public/browser_state.h"
+#include "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #include "ios/web/public/navigation_item.h"
 #include "ios/web/public/navigation_manager.h"
 #include "ios/web/public/referrer.h"
-#include "ios/web/public/web_state/js/crw_js_injection_receiver.h"
 #include "ios/web/public/web_state/navigation_context.h"
 #include "ios/web/public/web_state/web_state.h"
 #include "ui/base/page_transition_types.h"
diff --git a/components/translate/ios/browser/js_language_detection_manager.h b/components/translate/ios/browser/js_language_detection_manager.h
index 83a6065a..21b0a7a 100644
--- a/components/translate/ios/browser/js_language_detection_manager.h
+++ b/components/translate/ios/browser/js_language_detection_manager.h
@@ -10,7 +10,7 @@
 
 #include "base/callback_forward.h"
 #include "base/strings/string16.h"
-#import "ios/web/public/web_state/js/crw_js_injection_manager.h"
+#import "ios/web/public/deprecated/crw_js_injection_manager.h"
 
 namespace language_detection {
 
diff --git a/components/translate/ios/browser/js_translate_manager.h b/components/translate/ios/browser/js_translate_manager.h
index 3fdd067..6798248 100644
--- a/components/translate/ios/browser/js_translate_manager.h
+++ b/components/translate/ios/browser/js_translate_manager.h
@@ -5,7 +5,7 @@
 #ifndef COMPONENTS_TRANSLATE_IOS_BROWSER_JS_TRANSLATE_MANAGER_H_
 #define COMPONENTS_TRANSLATE_IOS_BROWSER_JS_TRANSLATE_MANAGER_H_
 
-#import "ios/web/public/web_state/js/crw_js_injection_manager.h"
+#import "ios/web/public/deprecated/crw_js_injection_manager.h"
 
 #include <string>
 
diff --git a/components/translate/ios/browser/js_translate_manager.mm b/components/translate/ios/browser/js_translate_manager.mm
index c8ab23cd..fba6e92 100644
--- a/components/translate/ios/browser/js_translate_manager.mm
+++ b/components/translate/ios/browser/js_translate_manager.mm
@@ -10,7 +10,7 @@
 
 #include "base/logging.h"
 #include "base/mac/bundle_locations.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
diff --git a/components/translate/ios/browser/js_translate_manager_unittest.mm b/components/translate/ios/browser/js_translate_manager_unittest.mm
index bcefdc1a..af64932 100644
--- a/components/translate/ios/browser/js_translate_manager_unittest.mm
+++ b/components/translate/ios/browser/js_translate_manager_unittest.mm
@@ -6,7 +6,7 @@
 
 #include "base/strings/sys_string_conversions.h"
 #include "components/grit/components_resources.h"
-#import "ios/web/public/test/fakes/crw_test_js_injection_receiver.h"
+#import "ios/web/public/deprecated/crw_test_js_injection_receiver.h"
 #import "ios/web/public/test/js_test_util.h"
 #import "testing/gtest_mac.h"
 #include "testing/platform_test.h"
diff --git a/components/url_formatter/url_formatter.h b/components/url_formatter/url_formatter.h
index 412cafd..18cc2781 100644
--- a/components/url_formatter/url_formatter.h
+++ b/components/url_formatter/url_formatter.h
@@ -57,7 +57,7 @@
   std::string matching_top_domain;
 };
 
-// Nothing is ommitted.
+// Nothing is omitted.
 extern const FormatUrlType kFormatUrlOmitNothing;
 
 // If set, any username and password are removed.
@@ -87,7 +87,7 @@
 // If the scheme is 'mailto:', it's removed. Not in kFormatUrlOmitDefaults.
 extern const FormatUrlType kFormatUrlOmitMailToScheme;
 
-// Convenience for omitting all unecessary types. Does not include HTTPS scheme
+// Convenience for omitting all unnecessary types. Does not include HTTPS scheme
 // removal, or experimental flags.
 extern const FormatUrlType kFormatUrlOmitDefaults;
 
diff --git a/components/viz/service/display/renderer_pixeltest.cc b/components/viz/service/display/renderer_pixeltest.cc
index 938854d2..0b7f3463 100644
--- a/components/viz/service/display/renderer_pixeltest.cc
+++ b/components/viz/service/display/renderer_pixeltest.cc
@@ -47,6 +47,7 @@
 
 using cc::RendererPixelTest;
 using cc::GLRendererPixelTest;
+using cc::SkiaRendererPixelTest;
 using gpu::gles2::GLES2Interface;
 
 namespace viz {
@@ -875,16 +876,12 @@
                force_aa_off);
 }
 
-using RendererTypes = ::testing::Types<GLRenderer,
-                                       SoftwareRenderer,
-                                       SkiaRenderer,
-                                       cc::GLRendererWithExpandedViewport,
-                                       cc::SoftwareRendererWithExpandedViewport
-#if defined(USE_X11)
-                                       ,
-                                       cc::VulkanSkiaRenderer
-#endif
-                                       >;
+using RendererTypes =
+    ::testing::Types<GLRenderer,
+                     SoftwareRenderer,
+                     SkiaRenderer,
+                     cc::GLRendererWithExpandedViewport,
+                     cc::SoftwareRendererWithExpandedViewport>;
 TYPED_TEST_SUITE(RendererPixelTest, RendererTypes);
 
 template <typename RendererType>
@@ -897,19 +894,14 @@
 
 // Test GLRenderer as well as SkiaRenderer.
 template <typename RendererType>
-class GPURendererPixelTest : public cc::RendererPixelTest<RendererType> {};
+class GLCapableRendererPixelTest : public cc::RendererPixelTest<RendererType> {
+};
 
-using GPURendererTypes = ::testing::Types<GLRenderer,
-                                          SkiaRenderer
-#if defined(USE_X11)
-                                          ,
-                                          cc::VulkanSkiaRenderer
-#endif
-                                          >;
-TYPED_TEST_SUITE(GPURendererPixelTest, GPURendererTypes);
+using GLCapableRendererTypes = ::testing::Types<GLRenderer, SkiaRenderer>;
+TYPED_TEST_SUITE(GLCapableRendererPixelTest, GLCapableRendererTypes);
 
 // TODO(crbug.com/939442): Fix these tests for SkiaRenderer and switch them over
-// to GPURendererPixelTest.
+// to GLCapableRendererPixelTest.
 template <typename RendererType>
 class GLOnlyRendererPixelTest : public cc::RendererPixelTest<RendererType> {};
 
@@ -1077,7 +1069,7 @@
 
 // TODO(backer): Blending is not correct for SkiaRenderer
 // (https://crbug.com/953284)
-TYPED_TEST(GPURendererPixelTest, DISABLED_SolidColorBlend) {
+TYPED_TEST(GLCapableRendererPixelTest, DISABLED_SolidColorBlend) {
   gfx::Rect rect(this->device_viewport_size_);
 
   int id = 1;
@@ -1182,7 +1174,7 @@
       cc::FuzzyPixelOffByOneComparator(true)));
 }
 
-TYPED_TEST(GPURendererPixelTest,
+TYPED_TEST(GLCapableRendererPixelTest,
            PremultipliedTextureWithBackgroundAndVertexOpacity) {
   gfx::Rect rect(this->device_viewport_size_);
 
@@ -1566,7 +1558,8 @@
 }
 
 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
-TYPED_TEST(GPURendererPixelTest, NonPremultipliedTextureWithoutBackground) {
+TYPED_TEST(GLCapableRendererPixelTest,
+           NonPremultipliedTextureWithoutBackground) {
   gfx::Rect rect(this->device_viewport_size_);
 
   int id = 1;
@@ -1596,7 +1589,7 @@
 }
 
 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
-TYPED_TEST(GPURendererPixelTest, NonPremultipliedTextureWithBackground) {
+TYPED_TEST(GLCapableRendererPixelTest, NonPremultipliedTextureWithBackground) {
   gfx::Rect rect(this->device_viewport_size_);
 
   int id = 1;
@@ -1694,9 +1687,7 @@
   std::unique_ptr<media::VideoResourceUpdater> video_resource_updater_;
 };
 
-// TODO(samans): Make these tests pass with Vulkan. https://crbug.com/960795
-using NonVulkanGPURendererTypes = ::testing::Types<GLRenderer, SkiaRenderer>;
-TYPED_TEST_SUITE(VideoRendererPixelTest, NonVulkanGPURendererTypes);
+TYPED_TEST_SUITE(VideoRendererPixelTest, GLCapableRendererTypes);
 
 template <typename RendererType>
 class VideoRendererPixelHiLoTest : public VideoRendererPixelTest<RendererType>,
@@ -2896,13 +2887,7 @@
 };
 
 // TODO(916318): The software renderer does not support background filters yet.
-using BackdropFilterRendererTypes = ::testing::Types<GLRenderer,
-                                                     SkiaRenderer
-#if defined(USE_X11)
-                                                     ,
-                                                     cc::VulkanSkiaRenderer
-#endif
-                                                     >;
+using BackdropFilterRendererTypes = ::testing::Types<GLRenderer, SkiaRenderer>;
 
 TYPED_TEST_SUITE(RendererPixelTestWithBackdropFilter,
                  BackdropFilterRendererTypes);
@@ -3044,7 +3029,7 @@
 }
 
 // Software renderer does not support anti-aliased edges.
-TYPED_TEST(GPURendererPixelTest, AntiAliasing) {
+TYPED_TEST(GLCapableRendererPixelTest, AntiAliasing) {
   gfx::Rect rect(this->device_viewport_size_);
 
   int id = 1;
@@ -3084,7 +3069,7 @@
 }
 
 // Software renderer does not support anti-aliased edges.
-TYPED_TEST(GPURendererPixelTest, AntiAliasingPerspective) {
+TYPED_TEST(GLCapableRendererPixelTest, AntiAliasingPerspective) {
   gfx::Rect rect(this->device_viewport_size_);
 
   std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(1, rect);
@@ -3122,7 +3107,7 @@
 
 // This test tests that anti-aliasing works for axis aligned quads.
 // Anti-aliasing is only supported in the gl and skia renderers.
-TYPED_TEST(GPURendererPixelTest, AxisAligned) {
+TYPED_TEST(GLCapableRendererPixelTest, AxisAligned) {
   gfx::Rect rect(this->device_viewport_size_);
 
   int id = 1;
@@ -3151,7 +3136,7 @@
 // This test tests that forcing anti-aliasing off works as expected for
 // solid color draw quads.
 // Anti-aliasing is only supported in the gl and skia renderers.
-TYPED_TEST(GPURendererPixelTest, SolidColorDrawQuadForceAntiAliasingOff) {
+TYPED_TEST(GLCapableRendererPixelTest, SolidColorDrawQuadForceAntiAliasingOff) {
   gfx::Rect rect(this->device_viewport_size_);
 
   int id = 1;
@@ -3189,7 +3174,7 @@
 // This test tests that forcing anti-aliasing off works as expected for
 // render pass draw quads.
 // Anti-aliasing is only supported in the gl and skia renderers.
-TYPED_TEST(GPURendererPixelTest, RenderPassDrawQuadForceAntiAliasingOff) {
+TYPED_TEST(GLCapableRendererPixelTest, RenderPassDrawQuadForceAntiAliasingOff) {
   gfx::Rect rect(this->device_viewport_size_);
 
   int root_pass_id = 1;
@@ -3247,7 +3232,7 @@
 // This test tests that forcing anti-aliasing off works as expected for
 // tile draw quads.
 // Anti-aliasing is only supported in the gl and skia renderers.
-TYPED_TEST(GPURendererPixelTest, TileDrawQuadForceAntiAliasingOff) {
+TYPED_TEST(GLCapableRendererPixelTest, TileDrawQuadForceAntiAliasingOff) {
   gfx::Rect rect(this->device_viewport_size_);
 
   SkBitmap bitmap;
@@ -3315,7 +3300,7 @@
 // This test tests that forcing anti-aliasing off works as expected while
 // blending is still enabled.
 // Anti-aliasing is only supported in the gl and skia renderers.
-TYPED_TEST(GPURendererPixelTest, BlendingWithoutAntiAliasing) {
+TYPED_TEST(GLCapableRendererPixelTest, BlendingWithoutAntiAliasing) {
   gfx::Rect rect(this->device_viewport_size_);
 
   int id = 1;
@@ -3343,7 +3328,7 @@
 }
 
 // Trilinear filtering is only supported in the gl renderer.
-TYPED_TEST(GPURendererPixelTest, TrilinearFiltering) {
+TYPED_TEST(GLCapableRendererPixelTest, TrilinearFiltering) {
   gfx::Rect viewport_rect(this->device_viewport_size_);
 
   int root_pass_id = 1;
@@ -3975,12 +3960,7 @@
 
 using FlippedOutputSurfaceRendererTypes =
     ::testing::Types<cc::GLRendererWithFlippedSurface,
-                     cc::SkiaRendererWithFlippedSurface
-#if defined(USE_X11)
-                     ,
-                     cc::VulkanSkiaRendererWithFlippedSurface
-#endif
-                     >;
+                     cc::SkiaRendererWithFlippedSurface>;
 
 TYPED_TEST_SUITE(RendererPixelTestWithFlippedOutputSurface,
                  FlippedOutputSurfaceRendererTypes);
@@ -4074,7 +4054,7 @@
       cc::ExactPixelComparator(true)));
 }
 
-TYPED_TEST(GPURendererPixelTest, CheckReadbackSubset) {
+TYPED_TEST(GLCapableRendererPixelTest, CheckReadbackSubset) {
   gfx::Rect viewport_rect(this->device_viewport_size_);
 
   int root_pass_id = 1;
@@ -4123,7 +4103,7 @@
       cc::ExactPixelComparator(true), &capture_rect));
 }
 
-TYPED_TEST(GPURendererPixelTest, TextureQuadBatching) {
+TYPED_TEST(GLCapableRendererPixelTest, TextureQuadBatching) {
   // This test verifies that multiple texture quads using the same resource
   // get drawn correctly.  It implicitly is trying to test that the
   // GLRenderer does the right thing with its draw quad cache.
@@ -4208,7 +4188,7 @@
       cc::FuzzyPixelOffByOneComparator(true)));
 }
 
-TYPED_TEST(GPURendererPixelTest, TileQuadClamping) {
+TYPED_TEST(GLCapableRendererPixelTest, TileQuadClamping) {
   gfx::Rect viewport(this->device_viewport_size_);
   bool contents_premultiplied = true;
   bool needs_blending = true;
@@ -4330,7 +4310,7 @@
   }
 }
 
-TYPED_TEST(GPURendererPixelTest, RoundedCornerSimpleTextureDrawQuad) {
+TYPED_TEST(GLCapableRendererPixelTest, RoundedCornerSimpleTextureDrawQuad) {
   gfx::Rect viewport_rect(this->device_viewport_size_);
   constexpr int kInset = 20;
   constexpr int kCornerRadius = 20;
@@ -4663,25 +4643,21 @@
       cc::ExactPixelComparator(true)));
 }
 
-using SkiaRendererTypes = ::testing::Types<SkiaRenderer
-#if defined(USE_X11)
-                                           ,
-                                           cc::VulkanSkiaRenderer
-#endif
-                                           >;
+using SkiaRendererTypes = ::testing::Types<SkiaRenderer>;
 TYPED_TEST_SUITE(SkiaRendererPixelTestWithOverdrawFeedback, SkiaRendererTypes);
 
-template <typename RendererType>
 class SkiaRendererPixelTestWithOverdrawFeedback
-    : public cc::RendererPixelTest<RendererType> {
+    : public cc::RendererPixelTest<SkiaRenderer> {
  protected:
-  void SetUp() override {
-    this->renderer_settings_.show_overdraw_feedback = true;
-    RendererPixelTest<RendererType>::SetUp();
-  }
+  void SetUp() override;
 };
 
-TYPED_TEST(SkiaRendererPixelTestWithOverdrawFeedback, TranslucentRectangles) {
+void SkiaRendererPixelTestWithOverdrawFeedback::SetUp() {
+  renderer_settings_.show_overdraw_feedback = true;
+  SkiaRendererPixelTest::SetUp();
+}
+
+TEST_F(SkiaRendererPixelTestWithOverdrawFeedback, TranslucentRectangles) {
   gfx::Rect rect(this->device_viewport_size_);
 
   int id = 1;
diff --git a/content/app_shim_remote_cocoa/DEPS b/content/app_shim_remote_cocoa/DEPS
index b7c90a35..1b2c229c 100644
--- a/content/app_shim_remote_cocoa/DEPS
+++ b/content/app_shim_remote_cocoa/DEPS
@@ -3,6 +3,7 @@
 # add any additional dependencies on content code.
 # https://crbug.com/958255
 include_rules = [
+  "+components/remote_cocoa/app_shim",
   "+content/app_shim_remote_cocoa",
   "+content/browser/accessibility/browser_accessibility_cocoa.h",
   "+content/browser/accessibility/browser_accessibility_mac.h",
diff --git a/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge_local.mm b/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge_local.mm
index ff68ebfa..2aa04c3 100644
--- a/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge_local.mm
+++ b/content/app_shim_remote_cocoa/render_widget_host_ns_view_bridge_local.mm
@@ -6,12 +6,12 @@
 
 #include "base/mac/scoped_cftyperef.h"
 #include "base/strings/sys_string_conversions.h"
+#include "components/remote_cocoa/app_shim/ns_view_ids.h"
 #include "content/app_shim_remote_cocoa/render_widget_host_ns_view_client_helper.h"
 #include "content/common/cursors/webcursor.h"
 #import "skia/ext/skia_utils_mac.h"
 #include "ui/accelerated_widget_mac/window_resize_helper_mac.h"
 #import "ui/base/cocoa/animation_utils.h"
-#include "ui/base/cocoa/ns_view_ids.h"
 #include "ui/display/screen.h"
 #include "ui/events/keycodes/dom/dom_code.h"
 #include "ui/gfx/mac/coordinate_conversion.h"
@@ -67,7 +67,7 @@
 
 void RenderWidgetHostNSViewBridgeLocal::SetParentWebContentsNSView(
     uint64_t parent_ns_view_id) {
-  NSView* parent_ns_view = ui::NSViewIds::GetNSView(parent_ns_view_id);
+  NSView* parent_ns_view = remote_cocoa::GetNSViewFromId(parent_ns_view_id);
   // If the browser passed an invalid handle, then there is no recovery.
   CHECK(parent_ns_view);
   // Set the frame and autoresizing mask of the RenderWidgetHostViewCocoa as is
diff --git a/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.h b/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.h
index 5ba043f..ffa8e11 100644
--- a/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.h
+++ b/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.h
@@ -11,9 +11,9 @@
 
 #import "base/mac/scoped_nsobject.h"
 #include "base/macros.h"
+#include "components/remote_cocoa/app_shim/ns_view_ids.h"
 #include "content/common/content_export.h"
 #include "content/public/common/web_contents_ns_view_bridge.mojom.h"
-#include "ui/base/cocoa/ns_view_ids.h"
 
 @class WebContentsViewCocoa;
 
@@ -55,7 +55,7 @@
   base::scoped_nsobject<WebContentsViewCocoa> cocoa_view_;
   mojom::WebContentsNSViewClientAssociatedPtr client_;
 
-  std::unique_ptr<ui::ScopedNSViewIdMapping> view_id_;
+  std::unique_ptr<remote_cocoa::ScopedNSViewIdMapping> view_id_;
 
   DISALLOW_COPY_AND_ASSIGN(WebContentsNSViewBridge);
 };
diff --git a/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.mm b/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.mm
index cdd5646..c5815d1 100644
--- a/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.mm
+++ b/content/app_shim_remote_cocoa/web_contents_ns_view_bridge.mm
@@ -4,6 +4,7 @@
 
 #include "content/app_shim_remote_cocoa/web_contents_ns_view_bridge.h"
 
+#include "components/remote_cocoa/app_shim/ns_view_ids.h"
 #import "content/app_shim_remote_cocoa/web_contents_view_cocoa.h"
 #include "content/browser/web_contents/web_contents_view_mac.h"
 #include "ui/gfx/image/image_skia_util_mac.h"
@@ -17,8 +18,8 @@
   cocoa_view_.reset(
       [[WebContentsViewCocoa alloc] initWithViewsHostableView:nullptr]);
   [cocoa_view_ setClient:client_.get()];
-  view_id_ =
-      std::make_unique<ui::ScopedNSViewIdMapping>(view_id, cocoa_view_.get());
+  view_id_ = std::make_unique<remote_cocoa::ScopedNSViewIdMapping>(
+      view_id, cocoa_view_.get());
 }
 
 WebContentsNSViewBridge::WebContentsNSViewBridge(
@@ -27,8 +28,8 @@
   cocoa_view_.reset([[WebContentsViewCocoa alloc]
       initWithViewsHostableView:web_contents_view]);
   [cocoa_view_ setClient:web_contents_view];
-  view_id_ =
-      std::make_unique<ui::ScopedNSViewIdMapping>(view_id, cocoa_view_.get());
+  view_id_ = std::make_unique<remote_cocoa::ScopedNSViewIdMapping>(
+      view_id, cocoa_view_.get());
 }
 
 WebContentsNSViewBridge::~WebContentsNSViewBridge() {
@@ -42,7 +43,7 @@
 }
 
 void WebContentsNSViewBridge::SetParentNSView(uint64_t parent_ns_view_id) {
-  NSView* parent_ns_view = ui::NSViewIds::GetNSView(parent_ns_view_id);
+  NSView* parent_ns_view = remote_cocoa::GetNSViewFromId(parent_ns_view_id);
   // If the browser passed an invalid handle, then there is no recovery.
   CHECK(parent_ns_view);
   [parent_ns_view addSubview:cocoa_view_];
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 55f6b2a..fd4ee39 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -2101,7 +2101,11 @@
       "sandbox_support_mac_impl.h",
       "sandbox_support_mac_impl.mm",
     ]
-    deps += [ "//ui/events:dom_keyboard_layout" ]
+    deps += [
+      "//components/remote_cocoa/app_shim",
+      "//components/remote_cocoa/browser",
+      "//ui/events:dom_keyboard_layout",
+    ]
   }
 
   if (!is_mac) {
diff --git a/content/browser/accessibility/ax_platform_node_textprovider_win_browsertest.cc b/content/browser/accessibility/ax_platform_node_textprovider_win_browsertest.cc
index 5210be9..8daaed2 100644
--- a/content/browser/accessibility/ax_platform_node_textprovider_win_browsertest.cc
+++ b/content/browser/accessibility/ax_platform_node_textprovider_win_browsertest.cc
@@ -152,26 +152,18 @@
   LoadInitialAccessibilityTreeFromHtml(std::string(R"HTML(
       <!DOCTYPE html>
       <html>
-        <head>
-          <style>
-            .overflow_y {
-              overflow-x: hidden;
-              overflow-y: visible;
-            }
-          </style>
-        </head>
         <body>
-          <div class='overflow_y' style='width: 110px; height: 40px;'>
-            <span>
-              A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
-            </span>
+          <div style='overflow: hidden visible; width: 10em; height: 2.4em;'>
+            <span style='white-space: pre-line;'>AAA BBB
+              CCCCCC
+              DDDDDD</span>
           </div>
         </body>
       </html>
   )HTML"));
 
-  auto* node = FindNode(ax::mojom::Role::kStaticText,
-                        "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z");
+  auto* node =
+      FindNode(ax::mojom::Role::kStaticText, "AAA BBB\nCCCCCC\nDDDDDD");
   ASSERT_NE(nullptr, node);
   EXPECT_TRUE(node->PlatformIsLeaf());
   EXPECT_EQ(0u, node->PlatformChildCount());
@@ -188,8 +180,8 @@
   ASSERT_HRESULT_SUCCEEDED(::SafeArrayAccessData(
       text_provider_ranges.Get(), reinterpret_cast<void**>(&array_data)));
 
-  EXPECT_UIA_TEXTRANGE_EQ(array_data[0], L"A B C D E F ");
-  EXPECT_UIA_TEXTRANGE_EQ(array_data[1], L"G H I J K L ");
+  EXPECT_UIA_TEXTRANGE_EQ(array_data[0], L"AAA BBB");
+  EXPECT_UIA_TEXTRANGE_EQ(array_data[1], L"CCCCCC");
 
   ASSERT_HRESULT_SUCCEEDED(::SafeArrayUnaccessData(text_provider_ranges.Get()));
   text_provider_ranges.Reset();
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc
index ef396e2f..b168e862 100644
--- a/content/browser/accessibility/browser_accessibility.cc
+++ b/content/browser/accessibility/browser_accessibility.cc
@@ -662,8 +662,10 @@
     // The text bounds queried are not in this subtree; skip it and continue.
     const int child_start_offset =
         std::max(start_offset - child_offset_in_parent, 0);
-    if (child_start_offset > child_inner_text_length)
+    if (child_start_offset > child_inner_text_length) {
+      child_offset_in_parent += child_inner_text_length;
       continue;
+    }
 
     // The text bounds queried have already been gathered; short circuit.
     const int child_end_offset =
diff --git a/content/browser/appcache/appcache_update_job.cc b/content/browser/appcache/appcache_update_job.cc
index afeb14b..220ef99e 100644
--- a/content/browser/appcache/appcache_update_job.cc
+++ b/content/browser/appcache/appcache_update_job.cc
@@ -272,7 +272,7 @@
                               is_new_pending_master_entry);
   }
 
-  BrowserThread::PostAfterStartupTask(
+  BrowserThread::PostBestEffortTask(
       FROM_HERE, base::ThreadTaskRunnerHandle::Get(),
       base::BindOnce(&AppCacheUpdateJob::FetchManifest,
                      weak_factory_.GetWeakPtr(), true));
diff --git a/content/browser/blob_storage/chrome_blob_storage_context.cc b/content/browser/blob_storage/chrome_blob_storage_context.cc
index 5610c0d..94588aa 100644
--- a/content/browser/blob_storage/chrome_blob_storage_context.cc
+++ b/content/browser/blob_storage/chrome_blob_storage_context.cc
@@ -122,7 +122,7 @@
           {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
            base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN});
       // Removes our old blob directories if they exist.
-      BrowserThread::PostAfterStartupTask(
+      BrowserThread::PostBestEffortTask(
           FROM_HERE, file_task_runner,
           base::BindOnce(&RemoveOldBlobStorageDirectories,
                          std::move(blob_storage_parent), blob_storage_dir));
@@ -149,9 +149,8 @@
                                         std::move(file_task_runner)));
   // Signal the BlobMemoryController when it's appropriate to calculate its
   // storage limits.
-  BrowserThread::PostAfterStartupTask(
-      FROM_HERE,
-      base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}),
+  base::PostTaskWithTraits(
+      FROM_HERE, {content::BrowserThread::IO, base::TaskPriority::BEST_EFFORT},
       base::BindOnce(&storage::BlobMemoryController::CalculateBlobStorageLimits,
                      context_->mutable_memory_controller()->GetWeakPtr()));
 }
diff --git a/content/browser/browser_context.cc b/content/browser/browser_context.cc
index 74bac2767..32ad7ed 100644
--- a/content/browser/browser_context.cc
+++ b/content/browser/browser_context.cc
@@ -617,12 +617,10 @@
 
   scoped_refptr<IndexedDBContext> indexed_db_context =
       storage_partition->GetIndexedDBContext();
-  // No task runner in unit tests.
-  if (indexed_db_context->TaskRunner()) {
-    indexed_db_context->TaskRunner()->PostTask(
-        FROM_HERE, base::BindOnce(&SaveSessionStateOnIndexedDBThread,
-                                  std::move(indexed_db_context)));
-  }
+  IndexedDBContext* const indexed_db_context_ptr = indexed_db_context.get();
+  indexed_db_context_ptr->TaskRunner()->PostTask(
+      FROM_HERE, base::BindOnce(&SaveSessionStateOnIndexedDBThread,
+                                std::move(indexed_db_context)));
 }
 
 void BrowserContext::SetDownloadManagerForTesting(
diff --git a/content/browser/frame_host/frame_tree.cc b/content/browser/frame_host/frame_tree.cc
index 664d2c2..f68548fd 100644
--- a/content/browser/frame_host/frame_tree.cc
+++ b/content/browser/frame_host/frame_tree.cc
@@ -408,6 +408,15 @@
     render_view_host_map_.erase(it);
 }
 
+void FrameTree::FrameUnloading(FrameTreeNode* frame) {
+  if (frame->frame_tree_node_id() == focused_frame_tree_node_id_)
+    focused_frame_tree_node_id_ = FrameTreeNode::kFrameTreeNodeInvalidId;
+
+  // Ensure frames that are about to be deleted aren't visible from the other
+  // processes anymore.
+  frame->render_manager()->ResetProxyHosts();
+}
+
 void FrameTree::FrameRemoved(FrameTreeNode* frame) {
   if (frame->frame_tree_node_id() == focused_frame_tree_node_id_)
     focused_frame_tree_node_id_ = FrameTreeNode::kFrameTreeNodeInvalidId;
diff --git a/content/browser/frame_host/frame_tree.h b/content/browser/frame_host/frame_tree.h
index ccccd552..646b2f4 100644
--- a/content/browser/frame_host/frame_tree.h
+++ b/content/browser/frame_host/frame_tree.h
@@ -222,6 +222,10 @@
   void AddRenderViewHostRef(RenderViewHostImpl* render_view_host);
   void ReleaseRenderViewHostRef(RenderViewHostImpl* render_view_host);
 
+  // This is called when the frame is about to be removed and started to run
+  // unload handlers.
+  void FrameUnloading(FrameTreeNode* frame);
+
   // This is only meant to be called by FrameTreeNode. Triggers calling
   // the listener installed by SetFrameRemoveListener.
   void FrameRemoved(FrameTreeNode* frame);
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index c7f0e5a7..25c1ae8 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -2156,6 +2156,8 @@
   // descendant frames to execute unload handlers. Start executing those
   // handlers now.
   StartPendingDeletionOnSubtree();
+  frame_tree_node_->frame_tree()->FrameUnloading(frame_tree_node_);
+
   // Some children with no unload handler may be eligible for immediate
   // deletion. Cut the dead branches now. This is a performance optimization.
   PendingDeletionCheckCompletedOnSubtree();  // Can delete |this|.
@@ -2454,9 +2456,11 @@
   // Start pending deletion on this frame and its children.
   DeleteRenderFrame(FrameDeleteIntention::kNotMainFrame);
   StartPendingDeletionOnSubtree();
+  frame_tree_node_->frame_tree()->FrameUnloading(frame_tree_node_);
+
   // Some children with no unload handler may be eligible for immediate
   // deletion. Cut the dead branches now. This is a performance optimization.
-  PendingDeletionCheckCompletedOnSubtree();
+  PendingDeletionCheckCompletedOnSubtree();  // May delete |this|.
 }
 
 void RenderFrameHostImpl::OnBeforeUnloadACK(
@@ -4539,6 +4543,8 @@
                 ? UnloadState::InProgress
                 : UnloadState::Completed;
       }
+
+      node->frame_tree()->FrameUnloading(node);
     }
   }
 }
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h
index 5f5742f..ee97888e9 100644
--- a/content/browser/frame_host/render_frame_host_impl.h
+++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -1063,6 +1063,12 @@
                            NavigationCommitInIframePendingDeletionABC);
   FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest,
                            CommittedOriginIncompatibleWithOriginLock);
+  FRIEND_TEST_ALL_PREFIXES(
+      SitePerProcessBrowserTest,
+      IsDetachedSubframeObservableDuringUnloadHandlerSameProcess);
+  FRIEND_TEST_ALL_PREFIXES(
+      SitePerProcessBrowserTest,
+      IsDetachedSubframeObservableDuringUnloadHandlerCrossProcess);
 
   class DroppedInterfaceRequestLogger;
 
diff --git a/content/browser/frame_host/render_frame_proxy_host.cc b/content/browser/frame_host/render_frame_proxy_host.cc
index 40b42d5..a28f8049 100644
--- a/content/browser/frame_host/render_frame_proxy_host.cc
+++ b/content/browser/frame_host/render_frame_proxy_host.cc
@@ -165,6 +165,13 @@
 bool RenderFrameProxyHost::InitRenderFrameProxy() {
   DCHECK(!render_frame_proxy_created_);
 
+  // If the current RenderFrameHost is pending deletion, no new proxies should
+  // be created for it, since this frame should no longer be visible from other
+  // processes. We can get here with postMessage while trying to recreate
+  // proxies for the sender.
+  if (!frame_tree_node_->current_frame_host()->is_active())
+    return false;
+
   // It is possible to reach this when the process is dead (in particular, when
   // creating proxies from CreateProxiesForChildFrame).  In that case, don't
   // create the proxy.  The process shouldn't be resurrected just to create
diff --git a/content/browser/gpu/gpu_internals_ui.cc b/content/browser/gpu/gpu_internals_ui.cc
index 7480d4e..836f490 100644
--- a/content/browser/gpu/gpu_internals_ui.cc
+++ b/content/browser/gpu/gpu_internals_ui.cc
@@ -304,6 +304,21 @@
       "RGBA visual ID", base::NumberToString(gpu_info.rgba_visual)));
 #endif
 
+  std::string buffer_formats;
+  for (int i = 0; i <= static_cast<int>(gfx::BufferFormat::LAST); ++i) {
+    const gfx::BufferFormat buffer_format = static_cast<gfx::BufferFormat>(i);
+    if (i > 0)
+      buffer_formats += ",  ";
+    buffer_formats += gfx::BufferFormatToString(buffer_format);
+    const bool supported = base::ContainsValue(
+        gpu_info.supported_buffer_formats_for_allocation_and_texturing,
+        buffer_format);
+    buffer_formats += supported ? ": supported" : ": not supported";
+  }
+  basic_info->Append(NewDescriptionValuePair(
+      "gfx::BufferFormats supported for allocation and texturing",
+      buffer_formats));
+
   return basic_info;
 }
 
diff --git a/content/browser/ppapi_plugin_process_host.cc b/content/browser/ppapi_plugin_process_host.cc
index 817fa41..3771315 100644
--- a/content/browser/ppapi_plugin_process_host.cc
+++ b/content/browser/ppapi_plugin_process_host.cc
@@ -32,6 +32,7 @@
 #include "content/public/common/sandboxed_process_launcher_delegate.h"
 #include "content/public/common/service_names.mojom.h"
 #include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/shared_impl/ppapi_permissions.h"
 #include "services/network/public/cpp/network_connection_tracker.h"
 #include "services/service_manager/sandbox/sandbox_type.h"
 #include "services/service_manager/sandbox/switches.h"
@@ -57,10 +58,16 @@
 class PpapiPluginSandboxedProcessLauncherDelegate
     : public content::SandboxedProcessLauncherDelegate {
  public:
-  explicit PpapiPluginSandboxedProcessLauncherDelegate(bool is_broker)
+  PpapiPluginSandboxedProcessLauncherDelegate(
+      bool is_broker,
+      const ppapi::PpapiPermissions& permissions)
 #if BUILDFLAG(USE_ZYGOTE_HANDLE) || defined(OS_WIN)
       : is_broker_(is_broker)
 #endif
+#if defined(OS_WIN)
+        ,
+        permissions_(permissions)
+#endif
   {
   }
 
@@ -98,6 +105,14 @@
     if (!sid.empty())
       service_manager::SandboxWin::AddAppContainerPolicy(policy, sid.c_str());
 
+    // Only Flash needs to be able to execute dynamic code.
+    if (!permissions_.HasPermission(ppapi::PERMISSION_FLASH)) {
+      sandbox::MitigationFlags flags = policy->GetDelayedProcessMitigations();
+      flags |= sandbox::MITIGATION_DYNAMIC_CODE_DISABLE;
+      if (sandbox::SBOX_ALL_OK != policy->SetDelayedProcessMitigations(flags))
+        return false;
+    }
+
     return true;
   }
 #endif  // OS_WIN
@@ -124,7 +139,10 @@
 
  private:
 #if BUILDFLAG(USE_ZYGOTE_HANDLE) || defined(OS_WIN)
-  bool is_broker_;
+  const bool is_broker_;
+#endif
+#if defined(OS_WIN)
+  const ppapi::PpapiPermissions permissions_;
 #endif
 
   DISALLOW_COPY_AND_ASSIGN(PpapiPluginSandboxedProcessLauncherDelegate);
@@ -421,7 +439,8 @@
   // we are not using a plugin launcher - having a plugin launcher means we need
   // to use another process instead of just forking the zygote.
   process_->Launch(
-      std::make_unique<PpapiPluginSandboxedProcessLauncherDelegate>(is_broker_),
+      std::make_unique<PpapiPluginSandboxedProcessLauncherDelegate>(
+          is_broker_, permissions_),
       std::move(cmd_line), true);
   return true;
 }
diff --git a/content/browser/site_per_process_unload_browsertest.cc b/content/browser/site_per_process_unload_browsertest.cc
index 6bb2885..a24dc3e 100644
--- a/content/browser/site_per_process_unload_browsertest.cc
+++ b/content/browser/site_per_process_unload_browsertest.cc
@@ -1016,6 +1016,230 @@
   }
 }
 
+// Regression test for https://crbug.com/960006.
+//
+// 1. Navigate to a1(a2(b3),c4),
+// 2. b3 has a slow unload handler.
+// 3. a2 navigates same process.
+// 4. When the new document is loaded, a message is sent to c4 to check it
+//    cannot see b3 anymore, even if b3 is still unloading.
+IN_PROC_BROWSER_TEST_F(
+    SitePerProcessBrowserTest,
+    IsDetachedSubframeObservableDuringUnloadHandlerSameProcess) {
+  GURL page_url(embedded_test_server()->GetURL(
+      "a.com", "/cross_site_iframe_factory.html?a(a(b),c)"));
+  EXPECT_TRUE(NavigateToURL(shell(), page_url));
+  RenderFrameHostImpl* node1 =
+      static_cast<WebContentsImpl*>(shell()->web_contents())
+          ->GetFrameTree()
+          ->root()
+          ->current_frame_host();
+  RenderFrameHostImpl* node2 = node1->child_at(0)->current_frame_host();
+  RenderFrameHostImpl* node3 = node2->child_at(0)->current_frame_host();
+  RenderFrameHostImpl* node4 = node1->child_at(1)->current_frame_host();
+  ASSERT_TRUE(ExecJs(node1, "window.name = 'node1'"));
+  ASSERT_TRUE(ExecJs(node2, "window.name = 'node2'"));
+  ASSERT_TRUE(ExecJs(node3, "window.name = 'node3'"));
+  ASSERT_TRUE(ExecJs(node4, "window.name = 'node4'"));
+
+  // Test sanity check.
+  EXPECT_EQ(true, EvalJs(node1, "!!top.node2.node3"));
+  EXPECT_EQ(true, EvalJs(node2, "!!top.node2.node3"));
+  EXPECT_EQ(true, EvalJs(node3, "!!top.node2.node3"));
+  EXPECT_EQ(true, EvalJs(node4, "!!top.node2.node3"));
+
+  // Simulate a long-running unload handler in |node3|.
+  auto detach_filter = base::MakeRefCounted<DropMessageFilter>(
+      FrameMsgStart, FrameHostMsg_Detach::ID);
+  node3->GetProcess()->AddFilter(detach_filter.get());
+  node2->DisableSwapOutTimerForTesting();
+  ASSERT_TRUE(ExecJs(node3, "window.onunload = ()=>{}"));
+
+  // Prepare |node4| to respond to postMessage with a report of whether it can
+  // still find |node3|.
+  const char* kPostMessageHandlerScript = R"(
+      window.postMessageGotData == false;
+      window.postMessageCallback = function() {};
+      function receiveMessage(event) {
+          console.log('node4 - receiveMessage...');
+
+          var can_node3_be_found = false;
+          try {
+            can_node3_be_found = !!top.node2.node3;
+          } catch(e) {
+            can_node3_be_found = false;
+          }
+
+          window.postMessageGotData = true;
+          window.postMessageData = can_node3_be_found;
+          window.postMessageCallback(window.postMessageData);
+      }
+      window.addEventListener("message", receiveMessage, false);
+  )";
+  ASSERT_TRUE(ExecJs(node4, kPostMessageHandlerScript));
+
+  // Make |node1| navigate |node2| same process and after the navigation
+  // succeeds, send a post message to |node4|. We expect that the effects of the
+  // commit should be visible to |node4| by the time it receives the posted
+  // message.
+  const char* kNavigationScript = R"(
+      var node2_frame = document.getElementsByTagName('iframe')[0];
+      node2_frame.onload = function() {
+          console.log('node2_frame.onload ...');
+          node4.postMessage('try to find node3', '*');
+      };
+      node2_frame.src = $1;
+  )";
+  GURL url = embedded_test_server()->GetURL("a.com", "/title1.html");
+  ASSERT_TRUE(ExecJs(node1, JsReplace(kNavigationScript, url)));
+
+  // Check if |node4| has seen |node3| even after |node2| navigation finished
+  // (no other frame should see |node3| after the navigation of its parent).
+  const char* kPostMessageResultsScript = R"(
+      new Promise(function (resolve, reject) {
+          if (window.postMessageGotData)
+            resolve(window.postMessageData);
+          else
+            window.postMessageCallback = resolve;
+      });
+  )";
+  EXPECT_EQ(false, EvalJs(node4, kPostMessageResultsScript));
+}
+
+// Regression test for https://crbug.com/960006.
+//
+// 1. Navigate to a1(a2(b3),c4),
+// 2. b3 has a slow unload handler.
+// 3. a2 navigates cross process.
+// 4. When the new document is loaded, a message is sent to c4 to check it
+//    cannot see b3 anymore, even if b3 is still unloading.
+//
+// Note: This test is the same as the above, except it uses a cross-process
+// navigation at step 3.
+IN_PROC_BROWSER_TEST_F(
+    SitePerProcessBrowserTest,
+    IsDetachedSubframeObservableDuringUnloadHandlerCrossProcess) {
+  GURL page_url(embedded_test_server()->GetURL(
+      "a.com", "/cross_site_iframe_factory.html?a(a(b),c)"));
+  EXPECT_TRUE(NavigateToURL(shell(), page_url));
+  RenderFrameHostImpl* node1 =
+      static_cast<WebContentsImpl*>(shell()->web_contents())
+          ->GetFrameTree()
+          ->root()
+          ->current_frame_host();
+  RenderFrameHostImpl* node2 = node1->child_at(0)->current_frame_host();
+  RenderFrameHostImpl* node3 = node2->child_at(0)->current_frame_host();
+  RenderFrameHostImpl* node4 = node1->child_at(1)->current_frame_host();
+  ASSERT_TRUE(ExecJs(node1, "window.name = 'node1'"));
+  ASSERT_TRUE(ExecJs(node2, "window.name = 'node2'"));
+  ASSERT_TRUE(ExecJs(node3, "window.name = 'node3'"));
+  ASSERT_TRUE(ExecJs(node4, "window.name = 'node4'"));
+
+  // Test sanity check.
+  EXPECT_EQ(true, EvalJs(node1, "!!top.node2.node3"));
+  EXPECT_EQ(true, EvalJs(node2, "!!top.node2.node3"));
+  EXPECT_EQ(true, EvalJs(node3, "!!top.node2.node3"));
+  EXPECT_EQ(true, EvalJs(node4, "!!top.node2.node3"));
+
+  // Add a long-running unload handler to |node3|.
+  auto detach_filter = base::MakeRefCounted<DropMessageFilter>(
+      FrameMsgStart, FrameHostMsg_Detach::ID);
+  node3->GetProcess()->AddFilter(detach_filter.get());
+  node2->DisableSwapOutTimerForTesting();
+  ASSERT_TRUE(ExecJs(node3, "window.onunload = ()=>{}"));
+
+  // Prepare |node4| to respond to postMessage with a report of whether it can
+  // still find |node3|.
+  const char* kPostMessageHandlerScript = R"(
+      window.postMessageGotData == false;
+      window.postMessageCallback = function() {};
+      function receiveMessage(event) {
+          console.log('node4 - receiveMessage...');
+
+          var can_node3_be_found = false;
+          try {
+            can_node3_be_found = !!top.node2.node3;
+          } catch(e) {
+            can_node3_be_found = false;
+          }
+
+          window.postMessageGotData = true;
+          window.postMessageData = can_node3_be_found;
+          window.postMessageCallback(window.postMessageData);
+      }
+      window.addEventListener("message", receiveMessage, false);
+  )";
+  ASSERT_TRUE(ExecJs(node4, kPostMessageHandlerScript));
+
+  // Make |node1| navigate |node2| cross process and after the navigation
+  // succeeds, send a post message to |node4|. We expect that the effects of the
+  // commit should be visible to |node4| by the time it receives the posted
+  // message.
+  const char* kNavigationScript = R"(
+      var node2_frame = document.getElementsByTagName('iframe')[0];
+      node2_frame.onload = function() {
+          console.log('node2_frame.onload ...');
+          node4.postMessage('try to find node3', '*');
+      };
+      node2_frame.src = $1;
+  )";
+  GURL url = embedded_test_server()->GetURL("d.com", "/title1.html");
+  ASSERT_TRUE(ExecJs(node1, JsReplace(kNavigationScript, url)));
+
+  // Check if |node4| has seen |node3| even after |node2| navigation finished
+  // (no other frame should see |node3| after the navigation of its parent).
+  const char* kPostMessageResultsScript = R"(
+      new Promise(function (resolve, reject) {
+          if (window.postMessageGotData)
+            resolve(window.postMessageData);
+          else
+            window.postMessageCallback = resolve;
+      });
+  )";
+  EXPECT_EQ(false, EvalJs(node4, kPostMessageResultsScript));
+}
+
+// Regression test. https://crbug.com/963330
+// 1. Start from A1(B2,C3)
+// 2. B2 is the "focused frame", is deleted and starts unloading.
+// 3. C3 commits a new navigation before B2 has completed its unload.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, FocusedFrameUnload) {
+  // 1) Start from A1(B2,C3)
+  EXPECT_TRUE(NavigateToURL(
+      shell(), embedded_test_server()->GetURL(
+                   "a.com", "/cross_site_iframe_factory.html?a(b,c)")));
+  RenderFrameHostImpl* A1 = web_contents()->GetMainFrame();
+  RenderFrameHostImpl* B2 = A1->child_at(0)->current_frame_host();
+  RenderFrameHostImpl* C3 = A1->child_at(1)->current_frame_host();
+  FrameTree* frame_tree = A1->frame_tree_node()->frame_tree();
+
+  // 2.1) Make B2 to be the focused frame.
+  EXPECT_EQ(A1->frame_tree_node(), frame_tree->GetFocusedFrame());
+  EXPECT_TRUE(ExecJs(A1, "document.querySelector('iframe').focus()"));
+  EXPECT_EQ(B2->frame_tree_node(), frame_tree->GetFocusedFrame());
+
+  // 2.2 Unload B2. Drop detach message to simulate a long unloading.
+  auto filter = base::MakeRefCounted<DropMessageFilter>(
+      FrameMsgStart, FrameHostMsg_Detach::ID);
+  B2->GetProcess()->AddFilter(filter.get());
+
+  EXPECT_FALSE(B2->GetSuddenTerminationDisablerState(blink::kUnloadHandler));
+  EXPECT_TRUE(ExecJs(B2, "window.onunload = ()=>{};"));
+  EXPECT_TRUE(B2->GetSuddenTerminationDisablerState(blink::kUnloadHandler));
+
+  EXPECT_TRUE(B2->is_active());
+  EXPECT_TRUE(ExecJs(A1, "document.querySelector('iframe').remove()"));
+  EXPECT_EQ(nullptr, frame_tree->GetFocusedFrame());
+  EXPECT_EQ(2u, A1->child_count());
+  EXPECT_FALSE(B2->is_active());
+
+  // 3. C3 navigates.
+  NavigateFrameToURL(C3->frame_tree_node(),
+                     embedded_test_server()->GetURL("d.com", "/title1.html"));
+  EXPECT_TRUE(WaitForLoadStop(web_contents()));
+  EXPECT_EQ(2u, A1->child_count());
+}
+
 // Test the unload timeout is effective.
 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, UnloadTimeout) {
   GURL main_url(embedded_test_server()->GetURL(
diff --git a/content/browser/web_contents/DEPS b/content/browser/web_contents/DEPS
index 72b6930e8..a7b70c9 100644
--- a/content/browser/web_contents/DEPS
+++ b/content/browser/web_contents/DEPS
@@ -1,5 +1,6 @@
 specific_include_rules = {
   ".*_mac.*": [
+    "+components/remote_cocoa/browser/ns_view_ids.h",
     "+content/app_shim_remote_cocoa",
   ],
 }
diff --git a/content/browser/web_contents/web_contents_view_mac.mm b/content/browser/web_contents/web_contents_view_mac.mm
index 59198bf..7dbcc99 100644
--- a/content/browser/web_contents/web_contents_view_mac.mm
+++ b/content/browser/web_contents/web_contents_view_mac.mm
@@ -14,6 +14,7 @@
 #include "base/message_loop/message_loop_current.h"
 #import "base/message_loop/message_pump_mac.h"
 #include "base/threading/thread_restrictions.h"
+#include "components/remote_cocoa/browser/ns_view_ids.h"
 #include "content/app_shim_remote_cocoa/web_contents_ns_view_bridge.h"
 #import "content/app_shim_remote_cocoa/web_contents_view_cocoa.h"
 #include "content/browser/download/drag_download_file.h"
@@ -32,7 +33,6 @@
 #include "content/public/common/web_contents_ns_view_bridge.mojom-shared.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
 #include "ui/base/cocoa/cocoa_base_utils.h"
-#include "ui/base/cocoa/ns_view_ids.h"
 #include "ui/gfx/mac/coordinate_conversion.h"
 
 using blink::WebDragOperation;
@@ -89,7 +89,7 @@
                                        WebContentsViewDelegate* delegate)
     : web_contents_(web_contents),
       delegate_(delegate),
-      ns_view_id_(ui::NSViewIds::GetNewId()),
+      ns_view_id_(remote_cocoa::GetNewNSViewId()),
       ns_view_client_binding_(this),
       deferred_close_weak_ptr_factory_(this) {}
 
diff --git a/content/gpu/gpu_sandbox_hook_linux.cc b/content/gpu/gpu_sandbox_hook_linux.cc
index 6f4ef48..e3d4e13 100644
--- a/content/gpu/gpu_sandbox_hook_linux.cc
+++ b/content/gpu/gpu_sandbox_hook_linux.cc
@@ -137,6 +137,16 @@
 
   permissions->push_back(BrokerFilePermission::ReadWrite(kMali0Path));
   permissions->push_back(BrokerFilePermission::ReadWrite(kDevImageProc0Path));
+
+  // Non-privileged render nodes for format enumeration.
+  // https://dri.freedesktop.org/docs/drm/gpu/drm-uapi.html#render-nodes
+  base::FileEnumerator enumerator(
+      base::FilePath(FILE_PATH_LITERAL("/dev/dri/")), false /* recursive */,
+      base::FileEnumerator::FILES, FILE_PATH_LITERAL("renderD*"));
+  for (base::FilePath name = enumerator.Next(); !name.empty();
+       name = enumerator.Next()) {
+    permissions->push_back(BrokerFilePermission::ReadWrite(name.value()));
+  }
 }
 
 void AddImgPvrGpuWhitelist(std::vector<BrokerFilePermission>* permissions) {
diff --git a/content/public/test/content_test_suite_base.h b/content/public/test/content_test_suite_base.h
index 59c1b7c..2700f32 100644
--- a/content/public/test/content_test_suite_base.h
+++ b/content/public/test/content_test_suite_base.h
@@ -21,14 +21,14 @@
   // registered temporarily so that it can provide additional schemes.
   static void RegisterContentSchemes(ContentClient* content_client);
 
+  // Registers renderer/utility/gpu processes to run in-thread.
+  static void RegisterInProcessThreads();
+
  protected:
   ContentTestSuiteBase(int argc, char** argv);
 
   void Initialize() override;
 
-  // Registers renderer/utility/gpu processes to run in-thread.
-  void RegisterInProcessThreads();
-
  private:
   DISALLOW_COPY_AND_ASSIGN(ContentTestSuiteBase);
 };
diff --git a/docs/linux_debugging.md b/docs/linux_debugging.md
index a4d5532..478fc04 100644
--- a/docs/linux_debugging.md
+++ b/docs/linux_debugging.md
@@ -291,7 +291,7 @@
 Many of our tests bring up windows on screen. This can be annoying (they steal
 your focus) and hard to debug (they receive extra events as you mouse over them).
 Instead, use `Xvfb` or `Xephyr` to run a nested X session to debug them, as
-outlined on [web_tests_linux.md](web_tests_linux.md).
+outlined on [testing/web_tests_linux.md](testing/web_tests_linux.md).
 
 ### Browser tests
 
@@ -310,7 +310,7 @@
 
 ### Web tests
 
-See [web_tests_linux.md](web_tests_linux.md) for some tips. In particular,
+See [testing/web_tests_linux.md](testing/web_tests_linux.md) for some tips. In particular,
 note that it's possible to debug a web test via `ssh`ing to a Linux box; you
 don't need anything on screen if you use `Xvfb`.
 
@@ -449,7 +449,7 @@
 If you break in a debugger during a drag, Chrome will have grabbed your mouse
 and keyboard so you won't be able to interact with the debugger!  To work around
 this, run via `Xephyr`. Instructions for how to use `Xephyr` are on the
-[Running web tests on Linux](web_tests_linux.md) page.
+[Running web tests on Linux](testing/web_tests_linux.md) page.
 
 ## Tracking Down Bugs
 
diff --git a/docs/speed/perf_lab_platforms.md b/docs/speed/perf_lab_platforms.md
index 8eda03d4..39ac606 100644
--- a/docs/speed/perf_lab_platforms.md
+++ b/docs/speed/perf_lab_platforms.md
@@ -12,6 +12,8 @@
  * [android-nexus5x-perf](https://ci.chromium.org/p/chrome/builders/luci.chrome.ci/android-nexus5x-perf): Android MMB29Q.
  * [Android Nexus5X WebView Perf](https://ci.chromium.org/p/chrome/builders/luci.chrome.ci/Android%20Nexus5X%20WebView%20Perf): Android AOSP MOB30K.
  * [Android Nexus6 WebView Perf](https://ci.chromium.org/p/chrome/builders/luci.chrome.ci/Android%20Nexus6%20WebView%20Perf): Android AOSP MOB30K.
+ * [android-pixel2-perf](https://ci.chromium.org/p/chrome/builders/luci.chrome.ci/android-pixel2-perf): Android OPM1.171019.021.
+ * [android-pixel2_webview-perf](https://ci.chromium.org/p/chrome/builders/luci.chrome.ci/android-pixel2_webview-perf): Android OPM1.171019.021.
 
 ## Linux
 
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn
index 49703bc4..59f5892 100644
--- a/gpu/BUILD.gn
+++ b/gpu/BUILD.gn
@@ -314,6 +314,7 @@
     "command_buffer/tests/gl_tests_main.cc",
     "command_buffer/tests/gl_texture_mailbox_unittest.cc",
     "command_buffer/tests/gl_texture_storage_unittest.cc",
+    "command_buffer/tests/gl_unallocated_texture_unittest.cc",
     "command_buffer/tests/gl_unittest.cc",
     "command_buffer/tests/gl_unittests_android.cc",
     "command_buffer/tests/gl_virtual_contexts_ext_window_rectangles_unittest.cc",
diff --git a/gpu/command_buffer/service/external_vk_image_backing.cc b/gpu/command_buffer/service/external_vk_image_backing.cc
index b1cea134..b0b5e89 100644
--- a/gpu/command_buffer/service/external_vk_image_backing.cc
+++ b/gpu/command_buffer/service/external_vk_image_backing.cc
@@ -681,6 +681,16 @@
     DLOG_IF(ERROR, reads_in_progress_)
         << "Concurrent reading may cause problem.";
     ++reads_in_progress_;
+    // If a shared image is read repeatedly without any write access,
+    // |read_semaphore_handles_| will never be consumed and released, and then
+    // chrome will run out of file descriptors. To avoid this problem, we wait
+    // on read semaphores for readonly access too. And in most cases, a shared
+    // image is only read from one vulkan device queue, so it should not have
+    // performance impact.
+    // TODO(penghuang): avoid waiting on read semaphores.
+    *semaphore_handles = std::move(read_semaphore_handles_);
+    read_semaphore_handles_.clear();
+
     // A semaphore will become unsignaled, when it has been signaled and waited,
     // so it is not safe to reuse it.
     if (write_semaphore_handle_.is_valid())
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc
index 1bcfb4174..b070a4e4 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc
@@ -3870,8 +3870,8 @@
   scoped_refptr<MockGLImage> image(new MockGLImage);
   group().texture_manager()->SetTarget(texture_ref, GL_TEXTURE_EXTERNAL_OES);
   group().texture_manager()->SetLevelInfo(texture_ref, GL_TEXTURE_EXTERNAL_OES,
-                                          0, GL_RGBA, 0, 0, 1, 0, GL_RGBA,
-                                          GL_UNSIGNED_BYTE, gfx::Rect());
+                                          0, GL_RGBA, 1, 1, 1, 0, GL_RGBA,
+                                          GL_UNSIGNED_BYTE, gfx::Rect(1, 1));
   group().texture_manager()->SetLevelImage(texture_ref, GL_TEXTURE_EXTERNAL_OES,
                                            0, image.get(), Texture::BOUND);
 
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc
index 3af660fa..c1bb403 100644
--- a/gpu/command_buffer/service/texture_manager.cc
+++ b/gpu/command_buffer/service/texture_manager.cc
@@ -690,18 +690,15 @@
   if (target_ == 0)
     return CAN_RENDER_ALWAYS;
 
-  if (target_ != GL_TEXTURE_EXTERNAL_OES) {
-    if (face_infos_.empty() ||
-        static_cast<size_t>(base_level_) >= face_infos_[0].level_infos.size()) {
-      return CAN_RENDER_NEVER;
-    }
-    const Texture::LevelInfo& first_face =
-        face_infos_[0].level_infos[base_level_];
-    if (first_face.width == 0 ||
-        first_face.height == 0 ||
-        first_face.depth == 0) {
-      return CAN_RENDER_NEVER;
-    }
+  if (face_infos_.empty() ||
+      static_cast<size_t>(base_level_) >= face_infos_[0].level_infos.size()) {
+    return CAN_RENDER_NEVER;
+  }
+  const Texture::LevelInfo& first_face =
+      face_infos_[0].level_infos[base_level_];
+  if (first_face.width == 0 || first_face.height == 0 ||
+      first_face.depth == 0) {
+    return CAN_RENDER_NEVER;
   }
 
   if (target_ == GL_TEXTURE_CUBE_MAP && !cube_complete())
diff --git a/gpu/command_buffer/service/texture_manager_unittest.cc b/gpu/command_buffer/service/texture_manager_unittest.cc
index 70084fa..4a3de4b 100644
--- a/gpu/command_buffer/service/texture_manager_unittest.cc
+++ b/gpu/command_buffer/service/texture_manager_unittest.cc
@@ -756,12 +756,12 @@
   EXPECT_FALSE(TextureTestHelper::IsCubeComplete(texture));
   EXPECT_FALSE(manager_->CanGenerateMipmaps(texture_ref_.get()));
   EXPECT_TRUE(TextureTestHelper::IsNPOT(texture));
-  EXPECT_TRUE(manager_->CanRender(texture_ref_.get()));
+  EXPECT_FALSE(manager_->CanRender(texture_ref_.get()));
   EXPECT_TRUE(texture->SafeToRenderFrom());
   EXPECT_TRUE(texture->IsImmutable());
 }
 
-TEST_F(TextureTest, ZeroSizeCanNotRender) {
+TEST_F(TextureTest, ZeroSizeCanNotRender2D) {
   manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_2D);
   EXPECT_FALSE(manager_->CanRender(texture_ref_.get()));
   manager_->SetLevelInfo(texture_ref_.get(), GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1,
@@ -772,6 +772,19 @@
   EXPECT_FALSE(manager_->CanRender(texture_ref_.get()));
 }
 
+TEST_F(TextureTest, ZeroSizeCanNotRenderExternalOES) {
+  manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_EXTERNAL_OES);
+  EXPECT_FALSE(manager_->CanRender(texture_ref_.get()));
+  manager_->SetLevelInfo(texture_ref_.get(), GL_TEXTURE_EXTERNAL_OES, 0,
+                         GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                         gfx::Rect(1, 1));
+  EXPECT_TRUE(manager_->CanRender(texture_ref_.get()));
+  manager_->SetLevelInfo(texture_ref_.get(), GL_TEXTURE_EXTERNAL_OES, 0,
+                         GL_RGBA, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                         gfx::Rect());
+  EXPECT_FALSE(manager_->CanRender(texture_ref_.get()));
+}
+
 TEST_F(TextureTest, CanRenderTo) {
   TestHelper::SetupFeatureInfoInitExpectations(gl_.get(), "");
   scoped_refptr<FeatureInfo> feature_info(new FeatureInfo());
diff --git a/gpu/command_buffer/tests/gl_unallocated_texture_unittest.cc b/gpu/command_buffer/tests/gl_unallocated_texture_unittest.cc
new file mode 100644
index 0000000..f29feff2
--- /dev/null
+++ b/gpu/command_buffer/tests/gl_unallocated_texture_unittest.cc
@@ -0,0 +1,120 @@
+// Copyright 2019 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 <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "gpu/GLES2/gl2extchromium.h"
+#include "gpu/command_buffer/client/gles2_implementation.h"
+#include "gpu/command_buffer/client/gles2_lib.h"
+#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
+#include "gpu/command_buffer/tests/gl_manager.h"
+#include "gpu/command_buffer/tests/gl_test_utils.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gl/gl_share_group.h"
+
+namespace gpu {
+
+class GLUnallocatedTextureTest : public testing::Test {
+ protected:
+  void SetUp() override { gl_.Initialize(GLManager::Options()); }
+
+  void TearDown() override { gl_.Destroy(); }
+
+  GLuint MakeProgram(const char* fragment_shader) {
+    constexpr const char kVertexShader[] =
+        "void main() { gl_Position = vec4(0.0, 0.0, 0.0, 1.0); }";
+    GLuint program = GLTestHelper::LoadProgram(kVertexShader, fragment_shader);
+    if (!program)
+      return 0;
+    glUseProgram(program);
+
+    GLint location_sampler = glGetUniformLocation(program, "sampler");
+    glUniform1i(location_sampler, 0);
+    return program;
+  }
+
+  // Creates a texture on target, setting up filters but without setting any
+  // level image.
+  GLuint MakeUninitializedTexture(GLenum target) {
+    GLuint texture = 0;
+    glGenTextures(1, &texture);
+    glBindTexture(target, texture);
+    glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    return texture;
+  }
+
+  GLManager gl_;
+};
+
+// Test that we can render with GL_TEXTURE_2D textures that are unallocated.
+// This should not generate errors or assert.
+TEST_F(GLUnallocatedTextureTest, RenderUnallocatedTexture2D) {
+  constexpr const char kFragmentShader[] =
+      "uniform sampler2D sampler;\n"
+      "void main() { gl_FragColor = texture2D(sampler, vec2(0.0, 0.0)); }\n";
+  GLuint program = MakeProgram(kFragmentShader);
+  ASSERT_TRUE(program);
+  GLuint texture = MakeUninitializedTexture(GL_TEXTURE_2D);
+
+  glDrawArrays(GL_TRIANGLES, 0, 3);
+  EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
+
+  glDeleteTextures(1, &texture);
+  glDeleteProgram(program);
+}
+
+// Test that we can render with GL_TEXTURE_EXTERNAL_OES textures that are
+// unallocated. This should not generate errors or assert.
+TEST_F(GLUnallocatedTextureTest, RenderUnallocatedTextureExternal) {
+  if (!gl_.GetCapabilities().egl_image_external) {
+    LOG(INFO) << "GL_OES_EGL_image_external not supported, skipping test";
+    return;
+  }
+  constexpr const char kFragmentShader[] =
+      "#extension GL_OES_EGL_image_external : enable\n"
+      "uniform samplerExternalOES sampler;\n"
+      "void main() { gl_FragColor = texture2D(sampler, vec2(0.0, 0.0)); }\n";
+  GLuint program = MakeProgram(kFragmentShader);
+  ASSERT_TRUE(program);
+  GLuint texture = MakeUninitializedTexture(GL_TEXTURE_EXTERNAL_OES);
+
+  glDrawArrays(GL_TRIANGLES, 0, 3);
+  EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
+
+  glDeleteTextures(1, &texture);
+  glDeleteProgram(program);
+}
+
+// Test that we can render with GL_TEXTURE_RECTANGLE_ARB textures that are
+// unallocated. This should not generate errors or assert.
+TEST_F(GLUnallocatedTextureTest, RenderUnallocatedTextureRectange) {
+  if (!gl_.GetCapabilities().texture_rectangle) {
+    LOG(INFO) << "GL_ARB_texture_rectangle not supported, skipping test";
+    return;
+  }
+  constexpr const char kFragmentShader[] =
+      "#extension GL_ARB_texture_rectangle : enable\n"
+      "uniform sampler2DRect sampler;\n"
+      "void main() {\n"
+      "  gl_FragColor = texture2DRect(sampler, vec2(0.0, 0.0));\n"
+      "}\n";
+  GLuint program = MakeProgram(kFragmentShader);
+  ASSERT_TRUE(program);
+  GLuint texture = MakeUninitializedTexture(GL_TEXTURE_RECTANGLE_ARB);
+
+  glDrawArrays(GL_TRIANGLES, 0, 3);
+  EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
+
+  glDeleteTextures(1, &texture);
+  glDeleteProgram(program);
+}
+
+}  // namespace gpu
diff --git a/gpu/config/gpu_info.cc b/gpu/config/gpu_info.cc
index 01769df..b3d4d1c 100644
--- a/gpu/config/gpu_info.cc
+++ b/gpu/config/gpu_info.cc
@@ -6,6 +6,8 @@
 
 #include "gpu/config/gpu_info.h"
 
+#include "ui/gfx/buffer_format_util.h"
+
 namespace {
 
 void EnumerateGPUDevice(const gpu::GPUInfo::GPUDevice& device,
@@ -251,6 +253,9 @@
     ImageDecodeAcceleratorSupportedProfiles
         image_decode_accelerator_supported_profiles;
 
+    std::vector<gfx::BufferFormat>
+        supported_buffer_formats_for_allocation_and_texturing;
+
 #if defined(USE_X11)
     VisualID system_visual;
     VisualID rgba_visual;
@@ -274,8 +279,7 @@
     EnumerateGPUDevice(secondary_gpu, enumerator);
 
   enumerator->BeginAuxAttributes();
-  enumerator->AddTimeDeltaInSecondsF("initializationTime",
-                                     initialization_time);
+  enumerator->AddTimeDeltaInSecondsF("initializationTime", initialization_time);
   enumerator->AddBool("optimus", optimus);
   enumerator->AddBool("amdSwitchable", amd_switchable);
   enumerator->AddString("pixelShaderVersion", pixel_shader_version);
@@ -311,6 +315,8 @@
 #endif
   enumerator->AddInt("videoDecodeAcceleratorFlags",
                      video_decode_accelerator_capabilities.flags);
+
+  // TODO(crbug.com/966839): Fix the two supported profile dumping below.
   for (const auto& profile :
        video_decode_accelerator_capabilities.supported_profiles)
     EnumerateVideoDecodeAcceleratorSupportedProfile(profile, enumerator);
@@ -325,6 +331,14 @@
   enumerator->AddInt64("rgbaVisual", rgba_visual);
 #endif
   enumerator->AddBool("oopRasterizationSupported", oop_rasterization_supported);
+  std::string supported_formats;
+  for (const auto& format :
+       supported_buffer_formats_for_allocation_and_texturing) {
+    supported_formats += gfx::BufferFormatToString(format);
+    supported_formats += " ";
+  }
+  enumerator->AddString("supportedBufferFormatsForAllocationAndTexturing",
+                        supported_formats);
   enumerator->EndAuxAttributes();
 }
 
diff --git a/gpu/config/gpu_info.h b/gpu/config/gpu_info.h
index 8aef772..0e1a75ec 100644
--- a/gpu/config/gpu_info.h
+++ b/gpu/config/gpu_info.h
@@ -24,6 +24,10 @@
 typedef unsigned long VisualID;
 #endif
 
+namespace gfx {
+enum class BufferFormat;
+}
+
 namespace gpu {
 
 // These values are persisted to logs. Entries should not be renumbered and
@@ -330,6 +334,9 @@
   ImageDecodeAcceleratorSupportedProfiles
       image_decode_accelerator_supported_profiles;
 
+  std::vector<gfx::BufferFormat>
+      supported_buffer_formats_for_allocation_and_texturing;
+
 #if defined(USE_X11)
   VisualID system_visual;
   VisualID rgba_visual;
diff --git a/gpu/ipc/common/BUILD.gn b/gpu/ipc/common/BUILD.gn
index 9e4e036..adf97c5 100644
--- a/gpu/ipc/common/BUILD.gn
+++ b/gpu/ipc/common/BUILD.gn
@@ -206,6 +206,7 @@
     ":gpu_preferences_interface",
     "//mojo/public/mojom/base",
     "//ui/gfx/geometry/mojo",
+    "//ui/gfx/mojo",
   ]
 }
 
diff --git a/gpu/ipc/common/gpu_info.mojom b/gpu/ipc/common/gpu_info.mojom
index 954c46eb..e1e2f57 100644
--- a/gpu/ipc/common/gpu_info.mojom
+++ b/gpu/ipc/common/gpu_info.mojom
@@ -8,6 +8,7 @@
 import "gpu/ipc/common/dx_diag_node.mojom";
 import "mojo/public/mojom/base/time.mojom";
 import "ui/gfx/geometry/mojo/geometry.mojom";
+import "ui/gfx/mojo/buffer_types.mojom";
 
 // gpu::GPUInfo::GPUDevice
 struct GpuDevice {
@@ -162,6 +163,9 @@
   array<ImageDecodeAcceleratorSupportedProfile>
     image_decode_accelerator_supported_profiles;
 
+  array<gfx.mojom.BufferFormat>
+      supported_buffer_formats_for_allocation_and_texturing;
+
   uint64 system_visual;
   uint64 rgba_visual;
   bool oop_rasterization_supported;
diff --git a/gpu/ipc/common/gpu_info_struct_traits.cc b/gpu/ipc/common/gpu_info_struct_traits.cc
index 64ade57..8beda67 100644
--- a/gpu/ipc/common/gpu_info_struct_traits.cc
+++ b/gpu/ipc/common/gpu_info_struct_traits.cc
@@ -393,7 +393,9 @@
          data.ReadVideoEncodeAcceleratorSupportedProfiles(
              &out->video_encode_accelerator_supported_profiles) &&
          data.ReadImageDecodeAcceleratorSupportedProfiles(
-             &out->image_decode_accelerator_supported_profiles);
+             &out->image_decode_accelerator_supported_profiles) &&
+         data.ReadSupportedBufferFormatsForAllocationAndTexturing(
+             &out->supported_buffer_formats_for_allocation_and_texturing);
 }
 
 }  // namespace mojo
diff --git a/gpu/ipc/common/gpu_info_struct_traits.h b/gpu/ipc/common/gpu_info_struct_traits.h
index 9877fa47..390c0c5 100644
--- a/gpu/ipc/common/gpu_info_struct_traits.h
+++ b/gpu/ipc/common/gpu_info_struct_traits.h
@@ -11,6 +11,7 @@
 #include "gpu/ipc/common/dx_diag_node_struct_traits.h"
 #include "gpu/ipc/common/gpu_info.mojom.h"
 #include "ui/gfx/geometry/mojo/geometry_struct_traits.h"
+#include "ui/gfx/mojo/buffer_types_struct_traits.h"
 
 namespace mojo {
 
@@ -363,6 +364,12 @@
     return input.image_decode_accelerator_supported_profiles;
   }
 
+  static std::vector<gfx::BufferFormat>
+  supported_buffer_formats_for_allocation_and_texturing(
+      const gpu::GPUInfo& input) {
+    return input.supported_buffer_formats_for_allocation_and_texturing;
+  }
+
   static uint64_t system_visual(const gpu::GPUInfo& input) {
 #if defined(USE_X11)
     return input.system_visual;
diff --git a/gpu/ipc/service/gpu_init.cc b/gpu/ipc/service/gpu_init.cc
index 1b3c1086..4b413dd 100644
--- a/gpu/ipc/service/gpu_init.cc
+++ b/gpu/ipc/service/gpu_init.cc
@@ -33,6 +33,7 @@
 
 #if defined(USE_OZONE)
 #include "ui/ozone/public/ozone_platform.h"
+#include "ui/ozone/public/surface_factory_ozone.h"
 #endif
 
 #if defined(OS_WIN)
@@ -240,6 +241,10 @@
                                         .requires_mojo;
   params.viz_display_compositor = features::IsVizDisplayCompositorEnabled();
   ui::OzonePlatform::InitializeForGPU(params);
+  gpu_info_.supported_buffer_formats_for_allocation_and_texturing =
+      ui::OzonePlatform::GetInstance()
+          ->GetSurfaceFactoryOzone()
+          ->GetSupportedFormatsForTexturing();
 #endif
 
 #if BUILDFLAG(ENABLE_VULKAN)
@@ -439,6 +444,10 @@
                                         .requires_mojo;
   params.viz_display_compositor = features::IsVizDisplayCompositorEnabled();
   ui::OzonePlatform::InitializeForGPU(params);
+  gpu_info_.supported_buffer_formats_for_allocation_and_texturing =
+      ui::OzonePlatform::GetInstance()
+          ->GetSurfaceFactoryOzone()
+          ->GetSupportedFormatsForTexturing();
   ui::OzonePlatform::GetInstance()->AfterSandboxEntry();
 #endif
   bool needs_more_info = true;
diff --git a/infra/config/cr-buildbucket.cfg b/infra/config/cr-buildbucket.cfg
index 21ea5ce..5a23e730 100644
--- a/infra/config/cr-buildbucket.cfg
+++ b/infra/config/cr-buildbucket.cfg
@@ -660,15 +660,15 @@
 }
 
 builder_mixins {
-  name: "xcode-mac-9e501"
+  name: "xcode-mac-9a235"
   caches: {
-    name: "xcode_mac_9e501"
-    path: "xcode_mac_9e501.app"
+    name: "xcode_mac_9a235"
+    path: "xcode_mac_9a235.app"
   }
   recipe {
     properties_j: <<END
     $depot_tools/osx_sdk: {
-      "sdk_version": "9e501"
+      "sdk_version": "9a235"
     }
     END
   }
@@ -1252,11 +1252,6 @@
     }
 
     builders {
-      name: "chromeos-daisy-rel"
-      mixins: "chromeos-ci"
-    }
-
-    builders {
       name: "linux-chromeos-code-coverage"
       mixins: "code-coverage"
       mixins: "fyi-ci"
@@ -3528,7 +3523,6 @@
     builders { mixins: "chromeos-try" name: "chromeos-amd64-generic-cfi-thin-lto-rel" }
     builders { mixins: "chromeos-try" name: "chromeos-amd64-generic-rel" }
     builders { mixins: "chromeos-try" name: "chromeos-arm-generic-rel" }
-    builders { mixins: "chromeos-try" name: "chromeos-daisy-rel" }
     builders { mixins: "chromeos-try" name: "chromeos-kevin-compile-rel" }
     builders { mixins: "chromeos-try" name: "chromeos-kevin-rel" }
     builders { mixins: "chromeos-try" name: "linux-chromeos-compile-dbg" }
@@ -3835,7 +3829,7 @@
     builders {
       mixins: "mac-try"
       mixins: "upload_clang"
-      mixins: "xcode-mac-9e501"
+      mixins: "xcode-mac-9a235"
       name: "mac_upload_clang"
     }
 
diff --git a/infra/config/luci-milo.cfg b/infra/config/luci-milo.cfg
index 9fa14ef..838fbc4 100644
--- a/infra/config/luci-milo.cfg
+++ b/infra/config/luci-milo.cfg
@@ -631,11 +631,6 @@
     short_name: "arm"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/chromeos-daisy-rel"
-    category: "chromium.chromiumos|simple|release"
-    short_name: "dsy"
-  }
-  builders {
     name: "buildbucket/luci.chromium.ci/chromeos-kevin-rel"
     category: "chromium.chromiumos|simple|release"
     short_name: "kvn"
@@ -1063,11 +1058,6 @@
     short_name: "arm"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/chromeos-daisy-rel"
-    category: "simple|release"
-    short_name: "dsy"
-  }
-  builders {
     name: "buildbucket/luci.chromium.ci/chromeos-kevin-rel"
     category: "simple|release"
     short_name: "kvn"
@@ -3759,9 +3749,6 @@
     name: "buildbucket/luci.chromium.try/chromeos-arm-generic-rel"
   }
   builders {
-    name: "buildbucket/luci.chromium.try/chromeos-daisy-rel"
-  }
-  builders {
     name: "buildbucket/luci.chromium.try/chromeos-kevin-compile-rel"
   }
   builders {
@@ -4368,9 +4355,6 @@
     name: "buildbucket/luci.chromium.try/chromeos-arm-generic-rel"
   }
   builders {
-    name: "buildbucket/luci.chromium.try/chromeos-daisy-rel"
-  }
-  builders {
     name: "buildbucket/luci.chromium.try/chromeos-kevin-rel"
   }
   builders {
diff --git a/infra/config/luci-scheduler.cfg b/infra/config/luci-scheduler.cfg
index f811051..4993bd34 100644
--- a/infra/config/luci-scheduler.cfg
+++ b/infra/config/luci-scheduler.cfg
@@ -322,7 +322,6 @@
   triggers: "chromeos-amd64-generic-rel-goma-latest"
   triggers: "chromeos-amd64-generic-rel-vm-tests"
   triggers: "chromeos-arm-generic-rel"
-  triggers: "chromeos-daisy-rel"
   triggers: "chromeos-kevin-rel"
   triggers: "chromeos-kevin-rel-hw-tests"
   triggers: "chromeos-vm-code-coverage"
@@ -1133,16 +1132,6 @@
 }
 
 job {
-  id: "chromeos-daisy-rel"
-  acl_sets: "default"
-  buildbucket: {
-    server: "cr-buildbucket.appspot.com"
-    bucket: "luci.chromium.ci"
-    builder: "chromeos-daisy-rel"
-  }
-}
-
-job {
   id: "chromeos-kevin-rel"
   acl_sets: "default"
   buildbucket: {
diff --git a/ios/build/bots/tests/eg2_tests.json b/ios/build/bots/tests/eg2_tests.json
index c4a8c19..af254bb 100644
--- a/ios/build/bots/tests/eg2_tests.json
+++ b/ios/build/bots/tests/eg2_tests.json
@@ -4,12 +4,12 @@
     ],
     "tests": [
         {
-            "app": "ios_chrome_smoke_eg2tests",
-            "host": "ios_chrome_eg2_test_app_host"
+            "app": "ios_chrome_smoke_eg2tests_module",
+            "host": "ios_chrome_eg2tests"
         },
         {
-            "app": "ios_web_shell_eg2tests",
-            "host": "ios_web_shell_test_app_host"
+            "app": "ios_web_shell_eg2tests_module",
+            "host": "ios_web_shell_eg2tests"
         }
     ]
 }
diff --git a/ios/chrome/browser/autofill/BUILD.gn b/ios/chrome/browser/autofill/BUILD.gn
index 097c7043d..4a5844b 100644
--- a/ios/chrome/browser/autofill/BUILD.gn
+++ b/ios/chrome/browser/autofill/BUILD.gn
@@ -70,7 +70,7 @@
     "//ios/chrome/browser/ui/image_util",
     "//ios/chrome/browser/ui/util",
     "//ios/chrome/common/ui_util",
-    "//ios/web",
+    "//ios/web/public/deprecated",
     "//ios/web/public/js_messaging",
     "//third_party/leveldatabase",
     "//third_party/libaddressinput",
@@ -120,7 +120,6 @@
     "//ios/chrome/browser/infobars",
     "//ios/chrome/browser/signin",
     "//ios/chrome/browser/ui/autofill",
-    "//ios/web",
     "//third_party/leveldatabase",
     "//ui/gfx/geometry",
     "//url",
@@ -165,7 +164,7 @@
     "//ios/chrome/browser/web:test_support",
     "//ios/chrome/browser/web:web_internal",
     "//ios/chrome/test/base",
-    "//ios/web",
+    "//ios/web/public/deprecated",
     "//ios/web/public/js_messaging",
     "//ios/web/public/test",
     "//testing/gtest",
@@ -513,6 +512,7 @@
     "//ios/testing/earl_grey:earl_grey_support",
     "//ios/third_party/earl_grey:earl_grey+link",
     "//ios/web:earl_grey_test_support",
+    "//ios/web/public/deprecated",
     "//ios/web/public/test:element_selector",
     "//ios/web/public/test/http_server",
   ]
diff --git a/ios/chrome/browser/autofill/autofill_controller_unittest.mm b/ios/chrome/browser/autofill/autofill_controller_unittest.mm
index 470f2f50..c39cb28 100644
--- a/ios/chrome/browser/autofill/autofill_controller_unittest.mm
+++ b/ios/chrome/browser/autofill/autofill_controller_unittest.mm
@@ -40,12 +40,12 @@
 #include "ios/chrome/browser/web/chrome_web_client.h"
 #import "ios/chrome/browser/web/chrome_web_test.h"
 #include "ios/chrome/browser/web_data_service_factory.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #include "ios/web/public/js_messaging/web_frame.h"
 #include "ios/web/public/js_messaging/web_frame_util.h"
 #import "ios/web/public/js_messaging/web_frames_manager.h"
 #import "ios/web/public/navigation_item.h"
 #import "ios/web/public/navigation_manager.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
 #import "ios/web/public/web_state/web_state.h"
 #import "testing/gtest_mac.h"
 
diff --git a/ios/chrome/browser/autofill/form_input_egtest.mm b/ios/chrome/browser/autofill/form_input_egtest.mm
index 8a0e1263..6c1e347 100644
--- a/ios/chrome/browser/autofill/form_input_egtest.mm
+++ b/ios/chrome/browser/autofill/form_input_egtest.mm
@@ -16,12 +16,12 @@
 #import "ios/chrome/test/earl_grey/chrome_error_util.h"
 #import "ios/chrome/test/earl_grey/chrome_matchers.h"
 #import "ios/chrome/test/earl_grey/chrome_test_case.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #import "ios/web/public/test/earl_grey/web_view_actions.h"
 #import "ios/web/public/test/earl_grey/web_view_matchers.h"
 #include "ios/web/public/test/element_selector.h"
 #import "ios/web/public/test/http_server/http_server.h"
 #include "ios/web/public/test/http_server/http_server_util.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
diff --git a/ios/chrome/browser/autofill/form_suggestion_controller.mm b/ios/chrome/browser/autofill/form_suggestion_controller.mm
index 1d60124..9d90146 100644
--- a/ios/chrome/browser/autofill/form_suggestion_controller.mm
+++ b/ios/chrome/browser/autofill/form_suggestion_controller.mm
@@ -20,9 +20,9 @@
 #import "ios/chrome/browser/autofill/form_suggestion_view.h"
 #import "ios/chrome/browser/passwords/password_generation_utils.h"
 #include "ios/chrome/browser/ui/util/ui_util.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #import "ios/web/public/js_messaging/web_frames_manager.h"
 #import "ios/web/public/url_scheme_util.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
 #import "ios/web/public/web_state/ui/crw_web_view_proxy.h"
 #import "ios/web/public/web_state/web_state.h"
 
diff --git a/ios/chrome/browser/autofill/js_autofill_manager_unittest.mm b/ios/chrome/browser/autofill/js_autofill_manager_unittest.mm
index 432bfe4..ee2e9da2 100644
--- a/ios/chrome/browser/autofill/js_autofill_manager_unittest.mm
+++ b/ios/chrome/browser/autofill/js_autofill_manager_unittest.mm
@@ -13,9 +13,9 @@
 #import "components/autofill/ios/browser/js_autofill_manager.h"
 #include "ios/chrome/browser/web/chrome_web_client.h"
 #import "ios/chrome/browser/web/chrome_web_test.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #include "ios/web/public/js_messaging/web_frame_util.h"
 #import "ios/web/public/test/js_test_util.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
 #import "ios/web/public/web_state/web_state.h"
 #import "testing/gtest_mac.h"
 
diff --git a/ios/chrome/browser/autofill/js_suggestion_manager_unittest.mm b/ios/chrome/browser/autofill/js_suggestion_manager_unittest.mm
index 8534e67..fdb1fe8 100644
--- a/ios/chrome/browser/autofill/js_suggestion_manager_unittest.mm
+++ b/ios/chrome/browser/autofill/js_suggestion_manager_unittest.mm
@@ -10,10 +10,10 @@
 #import "base/test/ios/wait_util.h"
 #import "ios/chrome/browser/web/chrome_web_client.h"
 #include "ios/chrome/browser/web/chrome_web_test.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #import "ios/web/public/js_messaging/web_frame.h"
 #import "ios/web/public/js_messaging/web_frames_manager.h"
 #import "ios/web/public/test/js_test_util.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
 #import "ios/web/public/web_state/web_state.h"
 #import "testing/gtest_mac.h"
 
diff --git a/ios/chrome/browser/find_in_page/BUILD.gn b/ios/chrome/browser/find_in_page/BUILD.gn
index be428735..a258b72 100644
--- a/ios/chrome/browser/find_in_page/BUILD.gn
+++ b/ios/chrome/browser/find_in_page/BUILD.gn
@@ -23,8 +23,8 @@
     "//base",
     "//ios/chrome/browser/metrics:ukm_url_recorder",
     "//ios/chrome/browser/web",
-    "//ios/web",
     "//ios/web/public",
+    "//ios/web/public/deprecated",
     "//ios/web/public/find_in_page",
     "//services/metrics/public/cpp:ukm_builders",
   ]
@@ -69,7 +69,7 @@
     "//ios/chrome/browser/metrics:ukm_url_recorder",
     "//ios/chrome/browser/web:test_support",
     "//ios/chrome/browser/web:web_internal",
-    "//ios/web",
+    "//ios/web/public/deprecated",
     "//ios/web/public/test",
     "//ios/web/public/test/fakes",
     "//testing/gtest",
diff --git a/ios/chrome/browser/find_in_page/find_in_page_controller.mm b/ios/chrome/browser/find_in_page/find_in_page_controller.mm
index 6d111a3..4094bd7 100644
--- a/ios/chrome/browser/find_in_page/find_in_page_controller.mm
+++ b/ios/chrome/browser/find_in_page/find_in_page_controller.mm
@@ -17,9 +17,9 @@
 #import "ios/chrome/browser/find_in_page/js_findinpage_manager.h"
 #include "ios/chrome/browser/metrics/ukm_url_recorder.h"
 #import "ios/chrome/browser/web/dom_altering_lock.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #import "ios/web/public/find_in_page/find_in_page_manager.h"
 #import "ios/web/public/find_in_page/find_in_page_manager_delegate_bridge.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
 #import "ios/web/public/web_state/ui/crw_web_view_proxy.h"
 #import "ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h"
 #import "ios/web/public/web_state/web_state.h"
diff --git a/ios/chrome/browser/find_in_page/find_in_page_js_unittest.mm b/ios/chrome/browser/find_in_page/find_in_page_js_unittest.mm
index 0bc2b4e0..e849147e 100644
--- a/ios/chrome/browser/find_in_page/find_in_page_js_unittest.mm
+++ b/ios/chrome/browser/find_in_page/find_in_page_js_unittest.mm
@@ -9,7 +9,7 @@
 #import "ios/chrome/browser/find_in_page/find_in_page_model.h"
 #import "ios/chrome/browser/find_in_page/js_findinpage_manager.h"
 #import "ios/chrome/browser/web/chrome_web_test.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #import "ios/web/public/web_state/ui/crw_web_view_proxy.h"
 #import "ios/web/public/web_state/web_state.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/ios/chrome/browser/find_in_page/js_findinpage_manager.h b/ios/chrome/browser/find_in_page/js_findinpage_manager.h
index 953903b..2fa4170 100644
--- a/ios/chrome/browser/find_in_page/js_findinpage_manager.h
+++ b/ios/chrome/browser/find_in_page/js_findinpage_manager.h
@@ -9,7 +9,7 @@
 #include <CoreGraphics/CGGeometry.h>
 
 #include "base/ios/block_types.h"
-#import "ios/web/public/web_state/js/crw_js_injection_manager.h"
+#import "ios/web/public/deprecated/crw_js_injection_manager.h"
 
 // Data from find in page.
 typedef struct FindInPageEntry {
diff --git a/ios/chrome/browser/find_in_page/js_findinpage_manager_unittest.mm b/ios/chrome/browser/find_in_page/js_findinpage_manager_unittest.mm
index aa74d57..4ab52154 100644
--- a/ios/chrome/browser/find_in_page/js_findinpage_manager_unittest.mm
+++ b/ios/chrome/browser/find_in_page/js_findinpage_manager_unittest.mm
@@ -8,7 +8,7 @@
 
 #import "base/test/ios/wait_util.h"
 #import "ios/chrome/browser/web/chrome_web_test.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #import "ios/web/public/web_state/web_state.h"
 #import "testing/gtest_mac.h"
 
diff --git a/ios/chrome/browser/metrics/BUILD.gn b/ios/chrome/browser/metrics/BUILD.gn
index 5552d63..59965713 100644
--- a/ios/chrome/browser/metrics/BUILD.gn
+++ b/ios/chrome/browser/metrics/BUILD.gn
@@ -83,7 +83,7 @@
     "//ios/chrome/common",
     "//ios/public/provider/chrome/browser",
     "//ios/public/provider/chrome/browser/user",
-    "//ios/web",
+    "//ios/web/public/deprecated",
     "//url",
   ]
 }
diff --git a/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.h b/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.h
index ebcb80e..17994e1 100644
--- a/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.h
+++ b/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.h
@@ -21,7 +21,7 @@
 #include "components/ukm/observers/history_delete_observer.h"
 #include "components/ukm/observers/sync_disable_observer.h"
 #import "ios/chrome/browser/metrics/incognito_web_state_observer.h"
-#include "ios/web/public/web_state/global_web_state_observer.h"
+#include "ios/web/public/deprecated/global_web_state_observer.h"
 
 class IOSChromeStabilityMetricsProvider;
 class PrefRegistrySimple;
diff --git a/ios/chrome/browser/metrics/ios_chrome_stability_metrics_provider.h b/ios/chrome/browser/metrics/ios_chrome_stability_metrics_provider.h
index d3dfd6bbe..cbf287a 100644
--- a/ios/chrome/browser/metrics/ios_chrome_stability_metrics_provider.h
+++ b/ios/chrome/browser/metrics/ios_chrome_stability_metrics_provider.h
@@ -8,7 +8,7 @@
 #include "base/macros.h"
 #include "components/metrics/metrics_provider.h"
 #include "components/metrics/stability_metrics_helper.h"
-#include "ios/web/public/web_state/global_web_state_observer.h"
+#include "ios/web/public/deprecated/global_web_state_observer.h"
 
 class PrefService;
 
diff --git a/ios/chrome/browser/passwords/BUILD.gn b/ios/chrome/browser/passwords/BUILD.gn
index 5a37d09..1d90f1a5 100644
--- a/ios/chrome/browser/passwords/BUILD.gn
+++ b/ios/chrome/browser/passwords/BUILD.gn
@@ -87,6 +87,7 @@
     "//ios/public/provider/chrome/browser/ui",
     "//ios/third_party/material_components_ios:material_components_ios",
     "//ios/web/common",
+    "//ios/web/public/deprecated",
     "//ios/web/public/js_messaging",
     "//net",
     "//third_party/material_design_icons:ic_account_circle",
diff --git a/ios/chrome/browser/passwords/password_controller.mm b/ios/chrome/browser/passwords/password_controller.mm
index 1482b1f4..4b9b4bc 100644
--- a/ios/chrome/browser/passwords/password_controller.mm
+++ b/ios/chrome/browser/passwords/password_controller.mm
@@ -62,10 +62,10 @@
 #include "ios/chrome/browser/web/tab_id_tab_helper.h"
 #include "ios/chrome/grit/ios_strings.h"
 #import "ios/web/common/origin_util.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #include "ios/web/public/js_messaging/web_frame.h"
 #include "ios/web/public/js_messaging/web_frame_util.h"
 #include "ios/web/public/url_scheme_util.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
 #import "ios/web/public/web_state/web_state.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "ui/base/l10n/l10n_util_mac.h"
diff --git a/ios/chrome/browser/prerender/BUILD.gn b/ios/chrome/browser/prerender/BUILD.gn
index 60ab091..9cb0c20f 100644
--- a/ios/chrome/browser/prerender/BUILD.gn
+++ b/ios/chrome/browser/prerender/BUILD.gn
@@ -35,7 +35,7 @@
     "//ios/chrome/browser/ui/ntp:util",
     "//ios/chrome/browser/web",
     "//ios/chrome/browser/web_state_list",
-    "//ios/web",
+    "//ios/web/public/deprecated",
     "//ui/base",
     "//url",
   ]
diff --git a/ios/chrome/browser/prerender/preload_controller.h b/ios/chrome/browser/prerender/preload_controller.h
index 8d5a055..8689e376 100644
--- a/ios/chrome/browser/prerender/preload_controller.h
+++ b/ios/chrome/browser/prerender/preload_controller.h
@@ -11,8 +11,8 @@
 
 #include "components/prefs/pref_change_registrar.h"
 #import "ios/chrome/browser/net/connection_type_observer_bridge.h"
+#import "ios/web/public/deprecated/crw_native_content_provider.h"
 #include "ios/web/public/referrer.h"
-#import "ios/web/public/web_state/ui/crw_native_content_provider.h"
 #import "ios/web/public/web_state/web_state_delegate_bridge.h"
 #import "net/url_request/url_fetcher.h"
 #include "ui/base/page_transition_types.h"
diff --git a/ios/chrome/browser/prerender/preload_controller.mm b/ios/chrome/browser/prerender/preload_controller.mm
index 814c1d4..973b8131 100644
--- a/ios/chrome/browser/prerender/preload_controller.mm
+++ b/ios/chrome/browser/prerender/preload_controller.mm
@@ -27,10 +27,10 @@
 #import "ios/chrome/browser/tabs/tab.h"
 #import "ios/chrome/browser/tabs/tab_helper_util.h"
 #import "ios/chrome/browser/tabs/tab_private.h"
+#import "ios/web/public/deprecated/crw_native_content.h"
+#import "ios/web/public/deprecated/crw_native_content_holder.h"
 #import "ios/web/public/navigation_item.h"
 #import "ios/web/public/navigation_manager.h"
-#import "ios/web/public/web_state/ui/crw_native_content.h"
-#import "ios/web/public/web_state/ui/crw_native_content_holder.h"
 #import "ios/web/public/web_state/web_state.h"
 #include "ios/web/public/web_state/web_state_observer_bridge.h"
 #import "ios/web/public/web_state/web_state_policy_decider_bridge.h"
diff --git a/ios/chrome/browser/reading_list/BUILD.gn b/ios/chrome/browser/reading_list/BUILD.gn
index 2d47225..034b4fc 100644
--- a/ios/chrome/browser/reading_list/BUILD.gn
+++ b/ios/chrome/browser/reading_list/BUILD.gn
@@ -46,8 +46,8 @@
     "//ios/chrome/browser/favicon",
     "//ios/chrome/browser/history",
     "//ios/chrome/common",
-    "//ios/web",
     "//ios/web/public",
+    "//ios/web/public/deprecated",
     "//ios/web/public/security",
     "//net",
     "//ui/base",
diff --git a/ios/chrome/browser/reading_list/reading_list_distiller_page.mm b/ios/chrome/browser/reading_list/reading_list_distiller_page.mm
index 766fb20..563e1a3f 100644
--- a/ios/chrome/browser/reading_list/reading_list_distiller_page.mm
+++ b/ios/chrome/browser/reading_list/reading_list_distiller_page.mm
@@ -12,10 +12,10 @@
 #include "components/favicon/ios/web_favicon_driver.h"
 #include "components/google/core/common/google_util.h"
 #include "ios/chrome/browser/reading_list/favicon_web_state_dispatcher_impl.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #import "ios/web/public/navigation_item.h"
 #import "ios/web/public/navigation_manager.h"
 #include "ios/web/public/security/ssl_status.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
 #import "ios/web/public/web_state/web_state.h"
 #import "net/base/mac/url_conversions.h"
 #include "net/cert/cert_status_flags.h"
diff --git a/ios/chrome/browser/tabs/BUILD.gn b/ios/chrome/browser/tabs/BUILD.gn
index b1eff512..2032415 100644
--- a/ios/chrome/browser/tabs/BUILD.gn
+++ b/ios/chrome/browser/tabs/BUILD.gn
@@ -133,6 +133,7 @@
     "//ios/public/provider/chrome/browser",
     "//ios/web",
     "//ios/web/public",
+    "//ios/web/public/deprecated",
     "//ios/web/public/security",
     "//ios/web/public/session",
     "//net",
diff --git a/ios/chrome/browser/tabs/tab.mm b/ios/chrome/browser/tabs/tab.mm
index 8f256928..e37d778 100644
--- a/ios/chrome/browser/tabs/tab.mm
+++ b/ios/chrome/browser/tabs/tab.mm
@@ -67,6 +67,7 @@
 #import "ios/chrome/browser/web/tab_id_tab_helper.h"
 #include "ios/chrome/grit/ios_strings.h"
 #import "ios/web/navigation/navigation_manager_impl.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #include "ios/web/public/favicon_status.h"
 #include "ios/web/public/favicon_url.h"
 #import "ios/web/public/navigation_item.h"
@@ -77,7 +78,6 @@
 #import "ios/web/public/session/serializable_user_data_manager.h"
 #include "ios/web/public/url_scheme_util.h"
 #include "ios/web/public/web_client.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
 #import "ios/web/public/web_state/navigation_context.h"
 #import "ios/web/public/web_state/web_state.h"
 #import "ios/web/public/web_state/web_state_observer_bridge.h"
diff --git a/ios/chrome/browser/translate/BUILD.gn b/ios/chrome/browser/translate/BUILD.gn
index bbf832c..857141fd 100644
--- a/ios/chrome/browser/translate/BUILD.gn
+++ b/ios/chrome/browser/translate/BUILD.gn
@@ -58,7 +58,7 @@
     "//ios/chrome/browser/ui/infobars:infobars_ui",
     "//ios/chrome/browser/ui/translate:translate_ui",
     "//ios/chrome/browser/ui/util",
-    "//ios/web",
+    "//ios/web/public/deprecated",
     "//third_party/metrics_proto",
     "//ui/base",
     "//ui/gfx",
@@ -88,6 +88,7 @@
     "//ios/chrome/common",
     "//ios/public/provider/chrome/browser:test_support",
     "//ios/web/public",
+    "//ios/web/public/deprecated",
     "//ios/web/public/test:util",
     "//skia",
     "//testing/gmock",
diff --git a/ios/chrome/browser/translate/js_language_detection_manager_unittest.mm b/ios/chrome/browser/translate/js_language_detection_manager_unittest.mm
index 6087065..5ecaba3b 100644
--- a/ios/chrome/browser/translate/js_language_detection_manager_unittest.mm
+++ b/ios/chrome/browser/translate/js_language_detection_manager_unittest.mm
@@ -14,8 +14,8 @@
 #include "base/values.h"
 #import "ios/chrome/browser/web/chrome_web_test.h"
 #include "ios/chrome/common/string_util.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #import "ios/web/public/test/js_test_util.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
 #import "ios/web/public/web_state/web_state.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/gtest_mac.h"
diff --git a/ios/chrome/browser/u2f/BUILD.gn b/ios/chrome/browser/u2f/BUILD.gn
index 7cebd98..2916fa9 100644
--- a/ios/chrome/browser/u2f/BUILD.gn
+++ b/ios/chrome/browser/u2f/BUILD.gn
@@ -30,7 +30,8 @@
     "//crypto",
     "//ios/chrome/browser",
     "//ios/chrome/common",
-    "//ios/web",
+    "//ios/web/public",
+    "//ios/web/public/deprecated",
     "//net",
     "//url",
   ]
@@ -49,7 +50,7 @@
     "//base",
     "//ios/chrome/browser",
     "//ios/chrome/browser/web:tab_id_tab_helper",
-    "//ios/web",
+    "//ios/web/public/deprecated",
     "//ios/web/public/test/fakes",
     "//net",
     "//testing/gmock",
diff --git a/ios/chrome/browser/u2f/u2f_controller.mm b/ios/chrome/browser/u2f/u2f_controller.mm
index ef3e9715d..f15abde 100644
--- a/ios/chrome/browser/u2f/u2f_controller.mm
+++ b/ios/chrome/browser/u2f/u2f_controller.mm
@@ -13,7 +13,7 @@
 #include "crypto/random.h"
 #import "ios/chrome/browser/chrome_url_util.h"
 #include "ios/chrome/common/x_callback_url.h"
-#include "ios/web/public/web_state/url_verification_constants.h"
+#include "ios/web/public/deprecated/url_verification_constants.h"
 #import "ios/web/public/web_state/web_state.h"
 #include "net/base/url_util.h"
 
diff --git a/ios/chrome/browser/u2f/u2f_controller_unittest.mm b/ios/chrome/browser/u2f/u2f_controller_unittest.mm
index d561373..92500371 100644
--- a/ios/chrome/browser/u2f/u2f_controller_unittest.mm
+++ b/ios/chrome/browser/u2f/u2f_controller_unittest.mm
@@ -9,8 +9,8 @@
 #import "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #import "ios/chrome/browser/chrome_url_util.h"
+#include "ios/web/public/deprecated/url_verification_constants.h"
 #import "ios/web/public/test/fakes/test_web_state.h"
-#include "ios/web/public/web_state/url_verification_constants.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
diff --git a/ios/chrome/browser/u2f/u2f_tab_helper_unittest.mm b/ios/chrome/browser/u2f/u2f_tab_helper_unittest.mm
index b09d2a94..6b59b85 100644
--- a/ios/chrome/browser/u2f/u2f_tab_helper_unittest.mm
+++ b/ios/chrome/browser/u2f/u2f_tab_helper_unittest.mm
@@ -10,8 +10,8 @@
 #include "base/strings/utf_string_conversions.h"
 #import "ios/chrome/browser/chrome_url_util.h"
 #import "ios/chrome/browser/web/tab_id_tab_helper.h"
+#include "ios/web/public/deprecated/url_verification_constants.h"
 #import "ios/web/public/test/fakes/test_web_state.h"
-#include "ios/web/public/web_state/url_verification_constants.h"
 #include "net/base/escape.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #import "testing/gtest_mac.h"
diff --git a/ios/chrome/browser/ui/autofill/BUILD.gn b/ios/chrome/browser/ui/autofill/BUILD.gn
index aa3dd65..8c479d7 100644
--- a/ios/chrome/browser/ui/autofill/BUILD.gn
+++ b/ios/chrome/browser/ui/autofill/BUILD.gn
@@ -57,7 +57,7 @@
     "//ios/public/provider/chrome/browser",
     "//ios/third_party/material_components_ios",
     "//ios/third_party/material_roboto_font_loader_ios",
-    "//ios/web",
+    "//ios/web/public/deprecated",
     "//ios/web/public/js_messaging",
     "//ui/base",
   ]
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory_mediator.mm b/ios/chrome/browser/ui/autofill/form_input_accessory_mediator.mm
index 6e5c0571..3bb74ad5 100644
--- a/ios/chrome/browser/ui/autofill/form_input_accessory_mediator.mm
+++ b/ios/chrome/browser/ui/autofill/form_input_accessory_mediator.mm
@@ -26,10 +26,10 @@
 #import "ios/chrome/browser/ui/util/keyboard_observer_helper.h"
 #include "ios/chrome/browser/ui/util/ui_util.h"
 #import "ios/chrome/browser/web_state_list/web_state_list.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #include "ios/web/public/js_messaging/web_frame.h"
 #include "ios/web/public/js_messaging/web_frames_manager.h"
 #import "ios/web/public/url_scheme_util.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
 #import "ios/web/public/web_state/web_state.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn b/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn
index ab17f1a..3b76356 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn
+++ b/ios/chrome/browser/ui/autofill/manual_fill/BUILD.gn
@@ -56,7 +56,8 @@
     "//ios/chrome/browser/ui/table_view:table_view",
     "//ios/chrome/browser/ui/util",
     "//ios/chrome/browser/web_state_list:web_state_list",
-    "//ios/web/public:public",
+    "//ios/web/public",
+    "//ios/web/public/deprecated",
     "//ios/web/public/js_messaging",
     "//ui/base:base",
   ]
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_injection_handler.mm b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_injection_handler.mm
index 644b1ba..6f30bbd 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_injection_handler.mm
+++ b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_injection_handler.mm
@@ -22,10 +22,10 @@
 #import "ios/chrome/browser/ui/autofill/manual_fill/form_observer_helper.h"
 #import "ios/chrome/browser/web_state_list/web_state_list.h"
 #include "ios/chrome/grit/ios_strings.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #include "ios/web/public/js_messaging/web_frame.h"
 #include "ios/web/public/js_messaging/web_frame_util.h"
 #include "ios/web/public/js_messaging/web_frames_manager.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
 #import "ios/web/public/web_state/web_state.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 #include "url/gurl.h"
diff --git a/ios/chrome/browser/ui/browser_view/BUILD.gn b/ios/chrome/browser/ui/browser_view/BUILD.gn
index fbeb45e..a4e248b 100644
--- a/ios/chrome/browser/ui/browser_view/BUILD.gn
+++ b/ios/chrome/browser/ui/browser_view/BUILD.gn
@@ -162,6 +162,7 @@
     "//ios/web",
     "//ios/web/common",
     "//ios/web/public",
+    "//ios/web/public/deprecated",
     "//third_party/google_toolbox_for_mac",
     "//ui/base",
     "//ui/gfx",
@@ -221,6 +222,7 @@
     "//ios/net",
     "//ios/testing:ocmock_support",
     "//ios/web/public",
+    "//ios/web/public/deprecated",
     "//ios/web/public/test",
     "//ios/web/public/test/fakes",
     "//ios/web/web_state:web_state_impl_header",
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
index 62e468a..6130515 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -204,16 +204,16 @@
 #import "ios/third_party/material_components_ios/src/components/Snackbar/src/MaterialSnackbar.h"
 #include "ios/web/common/features.h"
 #include "ios/web/common/referrer_util.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
+#import "ios/web/public/deprecated/crw_native_content_holder.h"
+#import "ios/web/public/deprecated/crw_native_content_provider.h"
 #include "ios/web/public/navigation_item.h"
 #import "ios/web/public/navigation_manager.h"
 #include "ios/web/public/url_scheme_util.h"
 #include "ios/web/public/user_agent.h"
 #include "ios/web/public/web_client.h"
 #import "ios/web/public/web_state/context_menu_params.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
 #import "ios/web/public/web_state/navigation_context.h"
-#import "ios/web/public/web_state/ui/crw_native_content_holder.h"
-#import "ios/web/public/web_state/ui/crw_native_content_provider.h"
 #import "ios/web/public/web_state/ui/crw_web_view_proxy.h"
 #import "ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h"
 #import "ios/web/public/web_state/web_state.h"
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm
index 11d3fb8..5b6ea9b 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm
@@ -58,13 +58,13 @@
 #include "ios/chrome/test/testing_application_context.h"
 #import "ios/net/protocol_handler_util.h"
 #import "ios/testing/ocmock_complex_type_helper.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
+#import "ios/web/public/deprecated/crw_native_content_provider.h"
 #include "ios/web/public/referrer.h"
 #import "ios/web/public/test/fakes/fake_navigation_context.h"
 #import "ios/web/public/test/fakes/test_navigation_manager.h"
 #import "ios/web/public/test/fakes/test_web_state.h"
 #include "ios/web/public/test/test_web_thread_bundle.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
-#import "ios/web/public/web_state/ui/crw_native_content_provider.h"
 #import "ios/web/web_state/ui/crw_web_controller.h"
 #import "ios/web/web_state/web_state_impl.h"
 #import "net/base/mac/url_conversions.h"
diff --git a/ios/chrome/browser/ui/ntp/BUILD.gn b/ios/chrome/browser/ui/ntp/BUILD.gn
index 309dc92..00c8f2f6 100644
--- a/ios/chrome/browser/ui/ntp/BUILD.gn
+++ b/ios/chrome/browser/ui/ntp/BUILD.gn
@@ -123,6 +123,7 @@
     "//ios/third_party/material_components_ios",
     "//ios/third_party/material_roboto_font_loader_ios",
     "//ios/web",
+    "//ios/web/public/deprecated",
     "//net",
     "//skia",
     "//ui/base",
diff --git a/ios/chrome/browser/ui/ntp/incognito_view_controller.h b/ios/chrome/browser/ui/ntp/incognito_view_controller.h
index af190d5d..3671b898 100644
--- a/ios/chrome/browser/ui/ntp/incognito_view_controller.h
+++ b/ios/chrome/browser/ui/ntp/incognito_view_controller.h
@@ -7,7 +7,7 @@
 
 #import <UIKit/UIKit.h>
 
-#import "ios/web/public/web_state/ui/crw_native_content.h"
+#import "ios/web/public/deprecated/crw_native_content.h"
 
 class UrlLoadingService;
 
diff --git a/ios/chrome/browser/ui/payments/BUILD.gn b/ios/chrome/browser/ui/payments/BUILD.gn
index 0ae58fe..e4cf8e75 100644
--- a/ios/chrome/browser/ui/payments/BUILD.gn
+++ b/ios/chrome/browser/ui/payments/BUILD.gn
@@ -92,6 +92,7 @@
     "//ios/third_party/material_roboto_font_loader_ios",
     "//ios/web/common",
     "//ios/web/public",
+    "//ios/web/public/deprecated",
     "//ios/web/public/js_messaging",
     "//ios/web/public/security",
     "//third_party/libaddressinput",
@@ -244,9 +245,9 @@
     "//ios/testing:ocmock_support",
     "//ios/third_party/material_components_ios",
     "//ios/web",
+    "//ios/web/public/deprecated:test_doubles",
     "//ios/web/public/js_messaging",
     "//ios/web/public/test",
-    "//ios/web/public/test/fakes",
     "//services/identity/public/cpp:cpp",
     "//services/identity/public/cpp:test_support",
     "//testing/gmock",
diff --git a/ios/chrome/browser/ui/payments/full_card_requester_unittest.mm b/ios/chrome/browser/ui/payments/full_card_requester_unittest.mm
index 51f2e4d4..aa87377 100644
--- a/ios/chrome/browser/ui/payments/full_card_requester_unittest.mm
+++ b/ios/chrome/browser/ui/payments/full_card_requester_unittest.mm
@@ -19,9 +19,9 @@
 #include "ios/chrome/browser/ui/autofill/card_unmask_prompt_view_bridge.h"
 #import "ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h"
 #import "ios/chrome/test/scoped_key_window.h"
+#import "ios/web/public/deprecated/crw_test_js_injection_receiver.h"
 #import "ios/web/public/js_messaging/web_frame_util.h"
 #import "ios/web/public/js_messaging/web_frames_manager.h"
-#import "ios/web/public/test/fakes/crw_test_js_injection_receiver.h"
 #include "ios/web/public/test/fakes/fake_web_frame.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
diff --git a/ios/chrome/browser/ui/payments/js_payment_request_manager.h b/ios/chrome/browser/ui/payments/js_payment_request_manager.h
index 267beb4d..58c1404 100644
--- a/ios/chrome/browser/ui/payments/js_payment_request_manager.h
+++ b/ios/chrome/browser/ui/payments/js_payment_request_manager.h
@@ -8,7 +8,7 @@
 #include "base/strings/string16.h"
 #include "components/payments/mojom/payment_request_data.mojom.h"
 #include "ios/chrome/browser/procedural_block_types.h"
-#import "ios/web/public/web_state/js/crw_js_injection_manager.h"
+#import "ios/web/public/deprecated/crw_js_injection_manager.h"
 
 namespace payments {
 class PaymentResponse;
diff --git a/ios/chrome/browser/ui/payments/payment_request_manager.mm b/ios/chrome/browser/ui/payments/payment_request_manager.mm
index 3ec2956..b8b02aa9 100644
--- a/ios/chrome/browser/ui/payments/payment_request_manager.mm
+++ b/ios/chrome/browser/ui/payments/payment_request_manager.mm
@@ -57,6 +57,8 @@
 #import "ios/chrome/browser/ui/payments/payment_request_coordinator.h"
 #import "ios/chrome/browser/ui/payments/payment_request_error_coordinator.h"
 #include "ios/web/common/origin_util.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
+#include "ios/web/public/deprecated/url_verification_constants.h"
 #include "ios/web/public/favicon_status.h"
 #include "ios/web/public/js_messaging/web_frame.h"
 #include "ios/web/public/js_messaging/web_frame_util.h"
@@ -65,10 +67,8 @@
 #include "ios/web/public/navigation_manager.h"
 #include "ios/web/public/security/ssl_status.h"
 #import "ios/web/public/url_scheme_util.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
 #import "ios/web/public/web_state/navigation_context.h"
 #import "ios/web/public/web_state/ui/crw_web_view_proxy.h"
-#include "ios/web/public/web_state/url_verification_constants.h"
 #import "ios/web/public/web_state/web_state.h"
 #import "ios/web/public/web_state/web_state_observer_bridge.h"
 #include "third_party/libaddressinput/chromium/chrome_metadata_source.h"
diff --git a/ios/chrome/browser/ui/settings/google_services/accounts_table_egtest.mm b/ios/chrome/browser/ui/settings/google_services/accounts_table_egtest.mm
index 847f782..1e54929 100644
--- a/ios/chrome/browser/ui/settings/google_services/accounts_table_egtest.mm
+++ b/ios/chrome/browser/ui/settings/google_services/accounts_table_egtest.mm
@@ -7,7 +7,6 @@
 
 #include "base/strings/sys_string_conversions.h"
 #include "components/strings/grit/components_strings.h"
-#include "components/sync/base/nigori.h"
 #include "components/sync/driver/profile_sync_service.h"
 #include "components/sync/driver/sync_service.h"
 #include "components/sync/engine/sync_encryption_handler.h"
diff --git a/ios/chrome/browser/ui/static_content/BUILD.gn b/ios/chrome/browser/ui/static_content/BUILD.gn
index 432873f..e97a092a 100644
--- a/ios/chrome/browser/ui/static_content/BUILD.gn
+++ b/ios/chrome/browser/ui/static_content/BUILD.gn
@@ -14,7 +14,7 @@
     "//base",
     "//ios/chrome/browser/browser_state",
     "//ios/chrome/browser/url_loading",
-    "//ios/web",
+    "//ios/web/public/deprecated",
     "//net",
     "//ui/base",
   ]
@@ -35,7 +35,7 @@
     "//ios/chrome/browser/browser_state:test_support",
     "//ios/chrome/browser/url_loading",
     "//ios/testing:ocmock_support",
-    "//ios/web",
+    "//ios/web/public/deprecated",
     "//ios/web/public/test",
     "//ios/web/public/test/fakes",
     "//net",
diff --git a/ios/chrome/browser/ui/static_content/static_html_native_content.h b/ios/chrome/browser/ui/static_content/static_html_native_content.h
index efcfd5f8..fe2eea1 100644
--- a/ios/chrome/browser/ui/static_content/static_html_native_content.h
+++ b/ios/chrome/browser/ui/static_content/static_html_native_content.h
@@ -7,8 +7,8 @@
 
 #import <UIKit/UIKit.h>
 
+#import "ios/web/public/deprecated/crw_native_content.h"
 #import "ios/web/public/navigation_manager.h"
-#import "ios/web/public/web_state/ui/crw_native_content.h"
 #include "ui/base/page_transition_types.h"
 
 class GURL;
diff --git a/ios/chrome/browser/ui/static_content/static_html_view_controller.mm b/ios/chrome/browser/ui/static_content/static_html_view_controller.mm
index b1d4381..0e0093e7 100644
--- a/ios/chrome/browser/ui/static_content/static_html_view_controller.mm
+++ b/ios/chrome/browser/ui/static_content/static_html_view_controller.mm
@@ -15,9 +15,9 @@
 #import "ios/chrome/browser/url_loading/url_loading_params.h"
 #import "ios/chrome/browser/url_loading/url_loading_service.h"
 #import "ios/chrome/browser/url_loading/url_loading_service_factory.h"
+#import "ios/web/public/deprecated/crw_context_menu_delegate.h"
+#import "ios/web/public/deprecated/crw_native_content.h"
 #import "ios/web/public/navigation_manager.h"
-#import "ios/web/public/web_state/ui/crw_context_menu_delegate.h"
-#import "ios/web/public/web_state/ui/crw_native_content.h"
 #import "ios/web/public/web_view_creation_util.h"
 #import "net/base/mac/url_conversions.h"
 #include "ui/base/page_transition_types.h"
diff --git a/ios/chrome/browser/ui/static_content/static_html_view_controller_unittest.mm b/ios/chrome/browser/ui/static_content/static_html_view_controller_unittest.mm
index d1537c5..8699694 100644
--- a/ios/chrome/browser/ui/static_content/static_html_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/static_content/static_html_view_controller_unittest.mm
@@ -14,12 +14,12 @@
 #include "ios/chrome/browser/url_loading/url_loading_service_factory.h"
 #include "ios/chrome/grit/ios_strings.h"
 #import "ios/testing/ocmock_complex_type_helper.h"
+#import "ios/web/public/deprecated/crw_native_content.h"
 #include "ios/web/public/referrer.h"
 #import "ios/web/public/test/fakes/test_web_client.h"
 #import "ios/web/public/test/js_test_util.h"
 #include "ios/web/public/test/scoped_testing_web_client.h"
 #include "ios/web/public/test/test_web_thread_bundle.h"
-#import "ios/web/public/web_state/ui/crw_native_content.h"
 #import "net/base/mac/url_conversions.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/gtest_mac.h"
diff --git a/ios/chrome/browser/ui/translate/BUILD.gn b/ios/chrome/browser/ui/translate/BUILD.gn
index ab67d428..5bcf310 100644
--- a/ios/chrome/browser/ui/translate/BUILD.gn
+++ b/ios/chrome/browser/ui/translate/BUILD.gn
@@ -92,8 +92,8 @@
     "//ios/chrome/browser/ui/translate/cells",
     "//ios/chrome/browser/web_state_list",
     "//ios/chrome/browser/web_state_list:test_support",
+    "//ios/web/public/deprecated:test_doubles",
     "//ios/web/public/test",
-    "//ios/web/public/test/fakes",
     "//skia",
     "//testing/gmock",
     "//testing/gtest",
diff --git a/ios/chrome/browser/ui/translate/translate_infobar_mediator_unittest.mm b/ios/chrome/browser/ui/translate/translate_infobar_mediator_unittest.mm
index 99c4186..9ee5f2a 100644
--- a/ios/chrome/browser/ui/translate/translate_infobar_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/translate/translate_infobar_mediator_unittest.mm
@@ -21,7 +21,7 @@
 #import "ios/chrome/browser/web_state_list/fake_web_state_list_delegate.h"
 #import "ios/chrome/browser/web_state_list/web_state_list.h"
 #import "ios/chrome/browser/web_state_list/web_state_opener.h"
-#import "ios/web/public/test/fakes/crw_test_js_injection_receiver.h"
+#import "ios/web/public/deprecated/crw_test_js_injection_receiver.h"
 #import "ios/web/public/test/fakes/test_navigation_manager.h"
 #import "ios/web/public/test/fakes/test_web_state.h"
 #include "ios/web/public/test/test_web_thread_bundle.h"
diff --git a/ios/chrome/browser/voice/BUILD.gn b/ios/chrome/browser/voice/BUILD.gn
index ab2dda5..d59fedf 100644
--- a/ios/chrome/browser/voice/BUILD.gn
+++ b/ios/chrome/browser/voice/BUILD.gn
@@ -59,6 +59,7 @@
     "//ios/chrome/browser/browser_state",
     "//ios/public/provider/chrome/browser/voice",
     "//ios/web",
+    "//ios/web/public/deprecated",
     "//net",
     "//third_party/google_toolbox_for_mac",
     "//url",
diff --git a/ios/chrome/browser/voice/text_to_speech_parser.mm b/ios/chrome/browser/voice/text_to_speech_parser.mm
index c61c4263..373ff99f3 100644
--- a/ios/chrome/browser/voice/text_to_speech_parser.mm
+++ b/ios/chrome/browser/voice/text_to_speech_parser.mm
@@ -5,7 +5,7 @@
 #import "ios/chrome/browser/voice/text_to_speech_parser.h"
 
 #include "base/logging.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #import "ios/web/public/web_state/web_state.h"
 #import "third_party/google_toolbox_for_mac/src/Foundation/GTMStringEncoding.h"
 
diff --git a/ios/chrome/browser/web/BUILD.gn b/ios/chrome/browser/web/BUILD.gn
index 99745ff1..3677cad 100644
--- a/ios/chrome/browser/web/BUILD.gn
+++ b/ios/chrome/browser/web/BUILD.gn
@@ -317,6 +317,7 @@
 
 source_set("eg_tests") {
   configs += [ "//build/config/compiler:enable_arc" ]
+  defines = [ "CHROME_EARL_GREY_1" ]
   testonly = true
   sources = [
     "browsing_egtest.mm",
@@ -372,6 +373,33 @@
   ]
 }
 
+source_set("eg2_tests") {
+  defines = [ "CHROME_EARL_GREY_2" ]
+  configs += [
+    "//build/config/compiler:enable_arc",
+    "//build/config/ios:xctest_config",
+  ]
+  testonly = true
+
+  sources = []
+
+  deps = [
+    "//components/content_settings/core/common",
+    "//ios/chrome/test/earl_grey:eg_test_support+eg2",
+    "//ios/net:test_support",
+    "//ios/testing:embedded_test_server_support",
+    "//ios/testing/earl_grey:eg_test_support+eg2",
+    "//ios/third_party/earl_grey2:test_lib",
+    "//ios/web/public/test:element_selector",
+    "//ios/web/public/test/http_server",
+    "//net:test_support",
+    "//ui/base",
+    "//url",
+  ]
+
+  libs = [ "UIKit.framework" ]
+}
+
 source_set("perf_tests") {
   configs += [ "//build/config/compiler:enable_arc" ]
   testonly = true
diff --git a/ios/chrome/browser/web/child_window_open_by_dom_egtest.mm b/ios/chrome/browser/web/child_window_open_by_dom_egtest.mm
index dca78b9..7d841bfe 100644
--- a/ios/chrome/browser/web/child_window_open_by_dom_egtest.mm
+++ b/ios/chrome/browser/web/child_window_open_by_dom_egtest.mm
@@ -2,14 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import <EarlGrey/EarlGrey.h>
-
 #include "base/strings/sys_string_conversions.h"
 #include "components/content_settings/core/common/content_settings.h"
 #import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
 #import "ios/chrome/test/earl_grey/chrome_error_util.h"
 #import "ios/chrome/test/earl_grey/chrome_matchers.h"
 #import "ios/chrome/test/earl_grey/chrome_test_case.h"
+#import "ios/testing/earl_grey/earl_grey_test.h"
 #import "ios/web/public/test/http_server/http_server.h"
 #include "ios/web/public/test/http_server/http_server_util.h"
 
@@ -39,8 +38,21 @@
 
 @implementation ChildWindowOpenByDOMTestCase
 
+#if defined(CHROME_EARL_GREY_2)
++ (void)setUpForTestCase {
+  [super setUpForTestCase];
+  [self setUpHelper];
+}
+#elif defined(CHROME_EARL_GREY_1)
 + (void)setUp {
   [super setUp];
+  [self setUpHelper];
+}
+#else
+#error Not an EarlGrey Test
+#endif
+
++ (void)setUpHelper {
   CHROME_EG_ASSERT_NO_ERROR(
       [ChromeEarlGrey setContentSettings:CONTENT_SETTING_ALLOW]);
   web::test::SetUpFileBasedHttpServer();
diff --git a/ios/chrome/browser/web/error_page_egtest.mm b/ios/chrome/browser/web/error_page_egtest.mm
index c1aff13..3fab31f 100644
--- a/ios/chrome/browser/web/error_page_egtest.mm
+++ b/ios/chrome/browser/web/error_page_egtest.mm
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import <EarlGrey/EarlGrey.h>
-
 #include <functional>
 #include <string>
 
@@ -11,6 +9,7 @@
 #import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
 #import "ios/chrome/test/earl_grey/chrome_error_util.h"
 #import "ios/chrome/test/earl_grey/chrome_test_case.h"
+#import "ios/testing/earl_grey/earl_grey_test.h"
 #include "ios/testing/embedded_test_server_handlers.h"
 #include "net/test/embedded_test_server/default_handlers.h"
 #include "net/test/embedded_test_server/http_request.h"
diff --git a/ios/chrome/browser/web/forms_egtest.mm b/ios/chrome/browser/web/forms_egtest.mm
index 20946f0..0ed58fa0 100644
--- a/ios/chrome/browser/web/forms_egtest.mm
+++ b/ios/chrome/browser/web/forms_egtest.mm
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import <EarlGrey/EarlGrey.h>
 #import <XCTest/XCTest.h>
 
 #include <memory>
@@ -19,6 +18,7 @@
 #import "ios/chrome/test/earl_grey/chrome_error_util.h"
 #import "ios/chrome/test/earl_grey/chrome_matchers.h"
 #import "ios/chrome/test/earl_grey/chrome_test_case.h"
+#import "ios/testing/earl_grey/earl_grey_test.h"
 #import "ios/testing/earl_grey/matchers.h"
 #import "ios/web/public/test/earl_grey/web_view_actions.h"
 #import "ios/web/public/test/earl_grey/web_view_matchers.h"
@@ -220,7 +220,7 @@
   // WKBasedNavigationManager presents repost confirmation dialog before loading
   // stops.
   if (web::GetWebClient()->IsSlimNavigationManagerEnabled()) {
-    [chrome_test_util::BrowserCommandDispatcherForMainBVC() reload];
+    [ChromeEarlGrey reload];
   } else {
     // Legacy navigation manager presents repost confirmation dialog after
     // loading stops.
@@ -257,7 +257,7 @@
   // [ChromeEarlGrey reload] because WKBasedNavigationManager presents repost
   // confirmation dialog before loading stops.
   if (web::GetWebClient()->IsSlimNavigationManagerEnabled()) {
-    [chrome_test_util::BrowserCommandDispatcherForMainBVC() reload];
+    [ChromeEarlGrey reload];
   }
 
   [self confirmResendWarning];
@@ -289,7 +289,7 @@
   // [ChromeEarlGrey reload] because WKBasedNavigationManager presents repost
   // confirmation dialog before loading stops.
   if (web::GetWebClient()->IsSlimNavigationManagerEnabled()) {
-    [chrome_test_util::BrowserCommandDispatcherForMainBVC() reload];
+    [ChromeEarlGrey reload];
   }
 
   [self confirmResendWarning];
@@ -355,7 +355,7 @@
   // [ChromeEarlGrey reload] because WKBasedNavigationManager presents repost
   // confirmation dialog before loading stops.
   if (web::GetWebClient()->IsSlimNavigationManagerEnabled()) {
-    [chrome_test_util::BrowserCommandDispatcherForMainBVC() reload];
+    [ChromeEarlGrey reload];
   }
 
   [[EarlGrey selectElementWithMatcher:ElementToDismissAlert(@"Cancel")]
@@ -403,7 +403,7 @@
   // WKBasedNavigationManager presents repost confirmation dialog before loading
   // stops.
   if (web::GetWebClient()->IsSlimNavigationManagerEnabled()) {
-    [chrome_test_util::BrowserCommandDispatcherForMainBVC() reload];
+    [ChromeEarlGrey reload];
   } else {
     // Legacy navigation manager presents repost confirmation dialog after
     // loading stops.
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey.mm b/ios/chrome/test/earl_grey/chrome_earl_grey.mm
index b25fe478..ee6c16d 100644
--- a/ios/chrome/test/earl_grey/chrome_earl_grey.mm
+++ b/ios/chrome/test/earl_grey/chrome_earl_grey.mm
@@ -27,10 +27,10 @@
 #import "ios/chrome/test/app/static_html_view_test_util.h"         // nogncheck
 #import "ios/chrome/test/app/sync_test_util.h"                     // nogncheck
 #import "ios/chrome/test/app/tab_test_util.h"                      // nogncheck
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"    // nogncheck
 #import "ios/web/public/test/earl_grey/js_test_util.h"             // nogncheck
 #import "ios/web/public/test/web_view_content_test_util.h"         // nogncheck
 #import "ios/web/public/test/web_view_interaction_test_util.h"     // nogncheck
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"  // nogncheck
 #import "ios/web/public/web_state/web_state.h"                     // nogncheck
 #include "ui/base/l10n/l10n_util.h"                                // nogncheck
 #endif
diff --git a/ios/chrome/test/earl_grey2/BUILD.gn b/ios/chrome/test/earl_grey2/BUILD.gn
index 9e4f66d..430cf83 100644
--- a/ios/chrome/test/earl_grey2/BUILD.gn
+++ b/ios/chrome/test/earl_grey2/BUILD.gn
@@ -9,22 +9,31 @@
 group("all_tests") {
   testonly = true
   deps = [
-    ":ios_chrome_eg2_test_app_host",
-    ":ios_chrome_smoke_eg2tests",
+    ":ios_chrome_eg2tests",
+    ":ios_chrome_smoke_eg2tests_module",
+    ":ios_chrome_web_eg2tests_module",
   ]
 }
 
-chrome_ios_eg2_test_app_host("ios_chrome_eg2_test_app_host") {
+chrome_ios_eg2_test_app_host("ios_chrome_eg2tests") {
 }
 
-chrome_ios_eg2_test("ios_chrome_smoke_eg2tests") {
-  xcode_test_application_name = "ios_chrome_eg2_test_app_host"
+chrome_ios_eg2_test("ios_chrome_smoke_eg2tests_module") {
+  xcode_test_application_name = "ios_chrome_eg2tests"
 
   deps = [
     "//ios/chrome/test/earl_grey2:eg2_tests",
   ]
 }
 
+chrome_ios_eg2_test("ios_chrome_web_eg2tests_module") {
+  xcode_test_application_name = "ios_chrome_eg2tests"
+
+  deps = [
+    "//ios/chrome/browser/web:eg2_tests",
+  ]
+}
+
 source_set("shared_helper_headers") {
   testonly = true
   sources = [
diff --git a/ios/chrome/test/earl_grey2/smoke_egtest.mm b/ios/chrome/test/earl_grey2/smoke_egtest.mm
index fb180ff..68c5799 100644
--- a/ios/chrome/test/earl_grey2/smoke_egtest.mm
+++ b/ios/chrome/test/earl_grey2/smoke_egtest.mm
@@ -147,7 +147,6 @@
 - (void)testAutofillProfileSyncToFakeServer {
   std::string fakeGUID = "b67e5ca1e09345d0aecfc2155c1f6b11";
   std::string profileName = "testAutofillProfileSyncToFakeServer";
-  [ChromeEarlGrey setUpFakeSyncServer];
 
   [ChromeEarlGrey clearAutofillProfileWithGUID:fakeGUID];
   GREYAssertTrue(![ChromeEarlGrey isAutofillProfilePresentWithGUID:fakeGUID
@@ -155,8 +154,6 @@
                  @"Autofill profile should not be present.");
   [ChromeEarlGrey injectAutofillProfileOnFakeSyncServerWithGUID:fakeGUID
                                             autofillProfileName:profileName];
-
-  [ChromeEarlGrey tearDownFakeSyncServer];
 }
 
 // Tests waitForSufficientlyVisibleElementWithMatcher in chrome_earl_grey.h
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn
index 130735d..cae9b29 100644
--- a/ios/web/BUILD.gn
+++ b/ios/web/BUILD.gn
@@ -113,6 +113,7 @@
     "//base/test:test_support",
     "//ios/testing/earl_grey:earl_grey_support",
     "//ios/third_party/earl_grey:earl_grey+link",
+    "//ios/web/public/deprecated",
     "//ios/web/public/test",
     "//ios/web/public/test:element_selector",
     "//ios/web/security",
@@ -140,6 +141,7 @@
     "//base/test:test_support",
     "//ios/testing/earl_grey:eg_app_support+eg2",
     "//ios/third_party/earl_grey2:app_framework+link",
+    "//ios/web/public/deprecated",
     "//ios/web/public/test",
     "//ios/web/security",
     "//net",
@@ -412,6 +414,7 @@
     "//ios/web/navigation",
     "//ios/web/navigation:wk_navigation_util",
     "//ios/web/public",
+    "//ios/web/public/deprecated",
     "//ios/web/public/security",
     "//ios/web/public/session",
     "//ios/web/public/test",
@@ -461,6 +464,7 @@
     "//ios/testing:ocmock_support",
     "//ios/web/find_in_page",
     "//ios/web/public",
+    "//ios/web/public/deprecated",
     "//ios/web/public/js_messaging",
     "//ios/web/public/test",
     "//ios/web/public/test/fakes",
@@ -506,9 +510,10 @@
     "//ios/web/navigation:block_universal_links_buildflags",
     "//ios/web/navigation:core",
     "//ios/web/public",
+    "//ios/web/public/deprecated",
+    "//ios/web/public/deprecated:test_doubles",
     "//ios/web/public/session",
     "//ios/web/public/test",
-    "//ios/web/public/test/fakes",
     "//ios/web/security",
     "//ios/web/test:mojo_bindings",
     "//ios/web/test:test_constants",
@@ -589,13 +594,14 @@
     "//ios/web/navigation",
     "//ios/web/navigation:core",
     "//ios/web/navigation:wk_navigation_util",
+    "//ios/web/public/deprecated",
+    "//ios/web/public/deprecated:test_doubles",
     "//ios/web/public/find_in_page",
     "//ios/web/public/js_messaging",
     "//ios/web/public/security",
     "//ios/web/public/session",
     "//ios/web/public/test",
     "//ios/web/public/test:element_selector",
-    "//ios/web/public/test/fakes",
     "//ios/web/public/test/http_server",
     "//ios/web/test:mojo_bindings",
     "//ios/web/test:packed_resources",
diff --git a/ios/web/navigation/BUILD.gn b/ios/web/navigation/BUILD.gn
index 8b13e40..996a24a 100644
--- a/ios/web/navigation/BUILD.gn
+++ b/ios/web/navigation/BUILD.gn
@@ -22,6 +22,7 @@
     "//ios/web/common",
     "//ios/web/navigation:wk_navigation_util",
     "//ios/web/public",
+    "//ios/web/public/deprecated",
     "//ios/web/public/download",
     "//ios/web/public/security",
     "//ios/web/public/session",
@@ -81,6 +82,7 @@
     "//components/url_formatter:url_formatter",
     "//ios/web/navigation:wk_navigation_util",
     "//ios/web/public",
+    "//ios/web/public/deprecated",
     "//ios/web/public/security",
     "//ui/base",
   ]
diff --git a/ios/web/navigation/crw_session_controller+private_constructors.h b/ios/web/navigation/crw_session_controller+private_constructors.h
index b10295d..3da4f09c 100644
--- a/ios/web/navigation/crw_session_controller+private_constructors.h
+++ b/ios/web/navigation/crw_session_controller+private_constructors.h
@@ -9,7 +9,7 @@
 #include <vector>
 
 #import "ios/web/navigation/crw_session_controller.h"
-#include "ios/web/public/navigation_item_list.h"
+#include "ios/web/public/deprecated/navigation_item_list.h"
 
 namespace web {
 class BrowserState;
diff --git a/ios/web/navigation/legacy_navigation_manager_impl.h b/ios/web/navigation/legacy_navigation_manager_impl.h
index 35faeb64..584fe97 100644
--- a/ios/web/navigation/legacy_navigation_manager_impl.h
+++ b/ios/web/navigation/legacy_navigation_manager_impl.h
@@ -12,7 +12,7 @@
 
 #include "base/macros.h"
 #import "ios/web/navigation/navigation_manager_impl.h"
-#import "ios/web/public/navigation_item_list.h"
+#import "ios/web/public/deprecated/navigation_item_list.h"
 #include "ios/web/public/reload_type.h"
 #include "ui/base/page_transition_types.h"
 #include "url/gurl.h"
diff --git a/ios/web/navigation/navigation_item_impl_list.h b/ios/web/navigation/navigation_item_impl_list.h
index 8db5001..a9455bec 100644
--- a/ios/web/navigation/navigation_item_impl_list.h
+++ b/ios/web/navigation/navigation_item_impl_list.h
@@ -5,7 +5,7 @@
 #ifndef IOS_WEB_NAVIGATION_NAVIGATION_ITEM_IMPL_LIST_H_
 #define IOS_WEB_NAVIGATION_NAVIGATION_ITEM_IMPL_LIST_H_
 
-#import "ios/web/public/navigation_item_list.h"
+#import "ios/web/public/deprecated/navigation_item_list.h"
 
 namespace web {
 
diff --git a/ios/web/navigation/navigation_manager_impl.h b/ios/web/navigation/navigation_manager_impl.h
index 670c5f11..55fd847 100644
--- a/ios/web/navigation/navigation_manager_impl.h
+++ b/ios/web/navigation/navigation_manager_impl.h
@@ -13,7 +13,7 @@
 #include "base/callback.h"
 #include "base/macros.h"
 #import "ios/web/navigation/navigation_item_impl.h"
-#import "ios/web/public/navigation_item_list.h"
+#import "ios/web/public/deprecated/navigation_item_list.h"
 #import "ios/web/public/navigation_manager.h"
 #include "ios/web/public/reload_type.h"
 #include "ui/base/page_transition_types.h"
diff --git a/ios/web/public/BUILD.gn b/ios/web/public/BUILD.gn
index 2277155..0816512c 100644
--- a/ios/web/public/BUILD.gn
+++ b/ios/web/public/BUILD.gn
@@ -8,6 +8,7 @@
   public_deps = [
     ":referrer",
     ":user_agent",
+    ":web_state_types",
     "//net",
     "//services/network/public/cpp",
     "//services/network/public/mojom",
@@ -15,6 +16,7 @@
 
   deps = [
     "//ios/web/common",
+    "//ios/web/public/deprecated",
     "//services/service_manager/public/cpp",
     "//ui/base",
   ]
@@ -30,8 +32,6 @@
     "java_script_dialog_presenter.h",
     "java_script_dialog_type.h",
     "navigation_item.h",
-    "navigation_item_list.h",
-    "navigation_item_list.mm",
     "navigation_manager.h",
     "reload_type.h",
     "security/cert_policy.h",
@@ -42,27 +42,16 @@
     "url_schemes.h",
     "url_schemes.mm",
     "web_client.h",
-    "web_state/context_menu_params.h",
-    "web_state/global_web_state_observer.h",
-    "web_state/js/crw_js_injection_evaluator.h",
-    "web_state/js/crw_js_injection_manager.h",
-    "web_state/js/crw_js_injection_receiver.h",
     "web_state/navigation_context.h",
     "web_state/page_display_state.h",
     "web_state/page_display_state.mm",
-    "web_state/ui/crw_context_menu_delegate.h",
-    "web_state/ui/crw_native_content.h",
-    "web_state/ui/crw_native_content_holder.h",
-    "web_state/ui/crw_native_content_provider.h",
     "web_state/ui/crw_web_view_proxy.h",
     "web_state/ui/crw_web_view_scroll_view_proxy.h",
-    "web_state/url_verification_constants.h",
     "web_state/web_state.h",
     "web_state/web_state_delegate.h",
     "web_state/web_state_delegate_bridge.h",
     "web_state/web_state_interface_provider.cc",
     "web_state/web_state_interface_provider.h",
-    "web_state/web_state_observer.h",
     "web_state/web_state_observer_bridge.h",
     "web_state/web_state_policy_decider.h",
     "web_state/web_state_policy_decider_bridge.h",
@@ -86,6 +75,22 @@
   configs += [ "//build/config/compiler:enable_arc" ]
 }
 
+# Un-separate this once the things in public/deprecated that need it are
+# deprecated.
+source_set("web_state_types") {
+  deps = [
+    ":referrer",
+    "//base",
+    "//url",
+  ]
+  sources = [
+    "web_state/context_menu_params.h",
+    "web_state/web_state_observer.h",
+  ]
+
+  configs += [ "//build/config/compiler:enable_arc" ]
+}
+
 # This is a separate target as it is used by Cronet.
 source_set("user_agent") {
   deps = [
diff --git a/ios/web/public/deprecated/BUILD.gn b/ios/web/public/deprecated/BUILD.gn
new file mode 100644
index 0000000..02df02d
--- /dev/null
+++ b/ios/web/public/deprecated/BUILD.gn
@@ -0,0 +1,48 @@
+# Copyright 2019 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.
+
+import("//ios/build/config.gni")
+
+source_set("deprecated") {
+  configs += [ "//build/config/compiler:enable_arc" ]
+
+  deps = [
+    "//base",
+    "//ios/web/public:web_state_types",
+    "//url",
+  ]
+  sources = [
+    "crw_context_menu_delegate.h",
+    "crw_js_injection_evaluator.h",
+    "crw_js_injection_manager.h",
+    "crw_js_injection_receiver.h",
+    "crw_native_content.h",
+    "crw_native_content_holder.h",
+    "crw_native_content_provider.h",
+    "global_web_state_observer.h",
+    "navigation_item_list.h",
+    "navigation_item_list.mm",
+    "url_verification_constants.h",
+  ]
+}
+
+source_set("test_doubles") {
+  configs += [ "//build/config/compiler:enable_arc" ]
+
+  deps = [
+    ":deprecated",
+    "//ios/web/public",
+    "//ios/web/web_state/ui:web_view_js_utils",
+    "//url",
+  ]
+
+  sources = [
+    "crw_test_js_injection_receiver.h",
+    "crw_test_js_injection_receiver.mm",
+    "test_native_content.h",
+    "test_native_content.mm",
+    "test_native_content_provider.h",
+    "test_native_content_provider.mm",
+  ]
+}
diff --git a/ios/web/public/deprecated/README.md b/ios/web/public/deprecated/README.md
new file mode 100644
index 0000000..124c9e0
--- /dev/null
+++ b/ios/web/public/deprecated/README.md
@@ -0,0 +1,6 @@
+This directory contains deprecated classes, structs and typedefs, and test doubles for
+those deprecated classes. New code should not import headers from this directory and no
+new functionality should be added to deprecated classes and functions. 
+
+This directory can be used as a temporary place for retiring public classes, structs and 
+typedefs.
\ No newline at end of file
diff --git a/ios/web/public/web_state/ui/crw_context_menu_delegate.h b/ios/web/public/deprecated/crw_context_menu_delegate.h
similarity index 79%
rename from ios/web/public/web_state/ui/crw_context_menu_delegate.h
rename to ios/web/public/deprecated/crw_context_menu_delegate.h
index 191166c..27c599a 100644
--- a/ios/web/public/web_state/ui/crw_context_menu_delegate.h
+++ b/ios/web/public/deprecated/crw_context_menu_delegate.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 IOS_WEB_PUBLIC_WEB_STATE_UI_CRW_CONTEXT_MENU_DELEGATE_H_
-#define IOS_WEB_PUBLIC_WEB_STATE_UI_CRW_CONTEXT_MENU_DELEGATE_H_
+#ifndef IOS_WEB_PUBLIC_DEPRECATED_CRW_CONTEXT_MENU_DELEGATE_H_
+#define IOS_WEB_PUBLIC_DEPRECATED_CRW_CONTEXT_MENU_DELEGATE_H_
 
 #import <WebKit/WebKit.h>
 
@@ -11,7 +11,7 @@
 
 // Implement this protocol to listen to the custom context menu trigger from
 // WKWebView.
-@protocol CRWContextMenuDelegate<NSObject>
+@protocol CRWContextMenuDelegate <NSObject>
 
 // Called when the custom Context menu recognizer triggers on |webView| by a
 // long press gesture. The system context menu will be suppressed.
@@ -27,4 +27,4 @@
     completionHandler:(void (^)(id, NSError*))completionHandler;
 @end
 
-#endif  // IOS_WEB_PUBLIC_WEB_STATE_UI_CRW_CONTEXT_MENU_DELEGATE_H_
+#endif  // IOS_WEB_PUBLIC_DEPRECATED_CRW_CONTEXT_MENU_DELEGATE_H_
diff --git a/ios/web/public/web_state/js/crw_js_injection_evaluator.h b/ios/web/public/deprecated/crw_js_injection_evaluator.h
similarity index 87%
rename from ios/web/public/web_state/js/crw_js_injection_evaluator.h
rename to ios/web/public/deprecated/crw_js_injection_evaluator.h
index 10cdea5..99ba3ae 100644
--- a/ios/web/public/web_state/js/crw_js_injection_evaluator.h
+++ b/ios/web/public/deprecated/crw_js_injection_evaluator.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 IOS_WEB_PUBLIC_WEB_STATE_JS_CRW_JS_INJECTION_EVALUATOR_H_
-#define IOS_WEB_PUBLIC_WEB_STATE_JS_CRW_JS_INJECTION_EVALUATOR_H_
+#ifndef IOS_WEB_PUBLIC_DEPRECATED_CRW_JS_INJECTION_EVALUATOR_H_
+#define IOS_WEB_PUBLIC_DEPRECATED_CRW_JS_INJECTION_EVALUATOR_H_
 
 #import <Foundation/Foundation.h>
 
@@ -33,4 +33,4 @@
 
 @end
 
-#endif  // IOS_WEB_PUBLIC_WEB_STATE_JS_CRW_JS_INJECTION_EVALUATOR_H_
+#endif  // IOS_WEB_PUBLIC_DEPRECATED_CRW_JS_INJECTION_EVALUATOR_H_
diff --git a/ios/web/public/web_state/js/crw_js_injection_manager.h b/ios/web/public/deprecated/crw_js_injection_manager.h
similarity index 89%
rename from ios/web/public/web_state/js/crw_js_injection_manager.h
rename to ios/web/public/deprecated/crw_js_injection_manager.h
index b9b29e4..bcc079a 100644
--- a/ios/web/public/web_state/js/crw_js_injection_manager.h
+++ b/ios/web/public/deprecated/crw_js_injection_manager.h
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_WEB_PUBLIC_WEB_STATE_JS_CRW_JS_INJECTION_MANAGER_H_
-#define IOS_WEB_PUBLIC_WEB_STATE_JS_CRW_JS_INJECTION_MANAGER_H_
+#ifndef IOS_WEB_PUBLIC_DEPRECATED_CRW_JS_INJECTION_MANAGER_H_
+#define IOS_WEB_PUBLIC_DEPRECATED_CRW_JS_INJECTION_MANAGER_H_
 
 #import <Foundation/Foundation.h>
 
-#import "ios/web/public/web_state/js/crw_js_injection_evaluator.h"
+#import "ios/web/public/deprecated/crw_js_injection_evaluator.h"
 
 @class CRWJSInjectionReceiver;
 
@@ -61,4 +61,4 @@
 
 @end
 
-#endif  // IOS_WEB_PUBLIC_WEB_STATE_JS_CRW_JS_INJECTION_MANAGER_H_
+#endif  // IOS_WEB_PUBLIC_DEPRECATED_CRW_JS_INJECTION_MANAGER_H_
diff --git a/ios/web/public/web_state/js/crw_js_injection_receiver.h b/ios/web/public/deprecated/crw_js_injection_receiver.h
similarity index 68%
rename from ios/web/public/web_state/js/crw_js_injection_receiver.h
rename to ios/web/public/deprecated/crw_js_injection_receiver.h
index f8fdfc58..753dcb4 100644
--- a/ios/web/public/web_state/js/crw_js_injection_receiver.h
+++ b/ios/web/public/deprecated/crw_js_injection_receiver.h
@@ -2,17 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_WEB_PUBLIC_WEB_STATE_JS_CRW_JS_INJECTION_RECEIVER_H_
-#define IOS_WEB_PUBLIC_WEB_STATE_JS_CRW_JS_INJECTION_RECEIVER_H_
+#ifndef IOS_WEB_PUBLIC_DEPRECATED_CRW_JS_INJECTION_RECEIVER_H_
+#define IOS_WEB_PUBLIC_DEPRECATED_CRW_JS_INJECTION_RECEIVER_H_
 
 #import <UIKit/UIKit.h>
 
-#import "ios/web/public/web_state/js/crw_js_injection_evaluator.h"
+#import "ios/web/public/deprecated/crw_js_injection_evaluator.h"
 
 @class CRWJSInjectionManager;
 
 // CRWJSInjectionReceiver injects JavaScript into a web view.
-@interface CRWJSInjectionReceiver : NSObject<CRWJSInjectionEvaluator>
+@interface CRWJSInjectionReceiver : NSObject <CRWJSInjectionEvaluator>
 
 // Init with JavaScript evaluator.
 - (id)initWithEvaluator:(id<CRWJSInjectionEvaluator>)evaluator;
@@ -28,4 +28,4 @@
 - (NSDictionary*)managers;
 @end
 
-#endif  // IOS_WEB_PUBLIC_WEB_STATE_JS_CRW_JS_INJECTION_RECEIVER_H_
+#endif  // IOS_WEB_PUBLIC_DEPRECATED_CRW_JS_INJECTION_RECEIVER_H_
diff --git a/ios/web/public/web_state/ui/crw_native_content.h b/ios/web/public/deprecated/crw_native_content.h
similarity index 91%
rename from ios/web/public/web_state/ui/crw_native_content.h
rename to ios/web/public/deprecated/crw_native_content.h
index a84f4d8..a2e3fa5 100644
--- a/ios/web/public/web_state/ui/crw_native_content.h
+++ b/ios/web/public/deprecated/crw_native_content.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 IOS_WEB_PUBLIC_WEB_STATE_UI_CRW_NATIVE_CONTENT_H_
-#define IOS_WEB_PUBLIC_WEB_STATE_UI_CRW_NATIVE_CONTENT_H_
+#ifndef IOS_WEB_PUBLIC_DEPRECATED_CRW_NATIVE_CONTENT_H_
+#define IOS_WEB_PUBLIC_DEPRECATED_CRW_NATIVE_CONTENT_H_
 
 #import <UIKit/UIKit.h>
 
@@ -17,7 +17,7 @@
 
 // Abstract methods needed for manipulating native content in the web content
 // area.
-@protocol CRWNativeContent<NSObject>
+@protocol CRWNativeContent <NSObject>
 
 // The page title, meant for display to the user. Will return nil if not
 // available.
@@ -86,7 +86,7 @@
 @end
 
 // CRWNativeContent delegate protocol.
-@protocol CRWNativeContentDelegate<NSObject>
+@protocol CRWNativeContentDelegate <NSObject>
 
 @optional
 // Called when the content supplies a new title.
@@ -98,4 +98,4 @@
 
 @end
 
-#endif  // IOS_WEB_PUBLIC_WEB_STATE_UI_CRW_NATIVE_CONTENT_H_
+#endif  // IOS_WEB_PUBLIC_DEPRECATED_CRW_NATIVE_CONTENT_H_
diff --git a/ios/web/public/web_state/ui/crw_native_content_holder.h b/ios/web/public/deprecated/crw_native_content_holder.h
similarity index 74%
rename from ios/web/public/web_state/ui/crw_native_content_holder.h
rename to ios/web/public/deprecated/crw_native_content_holder.h
index 7dc9bc08..c7fa12f6 100644
--- a/ios/web/public/web_state/ui/crw_native_content_holder.h
+++ b/ios/web/public/deprecated/crw_native_content_holder.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 IOS_WEB_PUBLIC_WEB_STATE_UI_CRW_NATIVE_CONTENT_HOLDER_H_
-#define IOS_WEB_PUBLIC_WEB_STATE_UI_CRW_NATIVE_CONTENT_HOLDER_H_
+#ifndef IOS_WEB_PUBLIC_DEPRECATED_CRW_NATIVE_CONTENT_HOLDER_H_
+#define IOS_WEB_PUBLIC_DEPRECATED_CRW_NATIVE_CONTENT_HOLDER_H_
 
 #import <Foundation/Foundation.h>
 
@@ -21,4 +21,4 @@
 
 @end
 
-#endif  // IOS_WEB_PUBLIC_WEB_STATE_UI_CRW_NATIVE_CONTENT_HOLDER_H_
+#endif  // IOS_WEB_PUBLIC_DEPRECATED_CRW_NATIVE_CONTENT_HOLDER_H_
diff --git a/ios/web/public/web_state/ui/crw_native_content_provider.h b/ios/web/public/deprecated/crw_native_content_provider.h
similarity index 83%
rename from ios/web/public/web_state/ui/crw_native_content_provider.h
rename to ios/web/public/deprecated/crw_native_content_provider.h
index 2feba845..5b46e25778 100644
--- a/ios/web/public/web_state/ui/crw_native_content_provider.h
+++ b/ios/web/public/deprecated/crw_native_content_provider.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 IOS_WEB_PUBLIC_WEB_STATE_UI_CRW_NATIVE_CONTENT_PROVIDER_H_
-#define IOS_WEB_PUBLIC_WEB_STATE_UI_CRW_NATIVE_CONTENT_PROVIDER_H_
+#ifndef IOS_WEB_PUBLIC_DEPRECATED_CRW_NATIVE_CONTENT_PROVIDER_H_
+#define IOS_WEB_PUBLIC_DEPRECATED_CRW_NATIVE_CONTENT_PROVIDER_H_
 #import <UIKit/UIKit.h>
 
 class GURL;
@@ -32,4 +32,4 @@
 
 @end
 
-#endif  // IOS_WEB_PUBLIC_WEB_STATE_UI_CRW_NATIVE_CONTENT_PROVIDER_H_
+#endif  // IOS_WEB_PUBLIC_DEPRECATED_CRW_NATIVE_CONTENT_PROVIDER_H_
diff --git a/ios/web/public/deprecated/crw_test_js_injection_receiver.h b/ios/web/public/deprecated/crw_test_js_injection_receiver.h
new file mode 100644
index 0000000..1f16c5f
--- /dev/null
+++ b/ios/web/public/deprecated/crw_test_js_injection_receiver.h
@@ -0,0 +1,15 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_WEB_PUBLIC_DEPRECATED_CRW_TEST_JS_INJECTION_RECEIVER_H_
+#define IOS_WEB_PUBLIC_DEPRECATED_CRW_TEST_JS_INJECTION_RECEIVER_H_
+
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
+
+// TestInjectionReceiver is used for tests.
+// It uses a bare UIWebView as backend for javascript evaluation.
+@interface CRWTestJSInjectionReceiver : CRWJSInjectionReceiver
+@end
+
+#endif  // IOS_WEB_PUBLIC_DEPRECATED_CRW_TEST_JS_INJECTION_RECEIVER_H_
diff --git a/ios/web/public/test/fakes/crw_test_js_injection_receiver.mm b/ios/web/public/deprecated/crw_test_js_injection_receiver.mm
similarity index 90%
rename from ios/web/public/test/fakes/crw_test_js_injection_receiver.mm
rename to ios/web/public/deprecated/crw_test_js_injection_receiver.mm
index bb30523..2d65937a 100644
--- a/ios/web/public/test/fakes/crw_test_js_injection_receiver.mm
+++ b/ios/web/public/deprecated/crw_test_js_injection_receiver.mm
@@ -2,19 +2,19 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/web/public/test/fakes/crw_test_js_injection_receiver.h"
+#import "ios/web/public/deprecated/crw_test_js_injection_receiver.h"
 
 #import <UIKit/UIKit.h>
 #import <WebKit/WebKit.h>
 
-#import "ios/web/public/web_state/js/crw_js_injection_evaluator.h"
+#import "ios/web/public/deprecated/crw_js_injection_evaluator.h"
 #import "ios/web/web_state/ui/web_view_js_utils.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
 #endif
 
-@interface CRWTestWKWebViewEvaluator : NSObject<CRWJSInjectionEvaluator> {
+@interface CRWTestWKWebViewEvaluator : NSObject <CRWJSInjectionEvaluator> {
   // Web view for JavaScript evaluation.
   WKWebView* _webView;
   // Set to track injected script managers.
diff --git a/ios/web/public/web_state/global_web_state_observer.h b/ios/web/public/deprecated/global_web_state_observer.h
similarity index 92%
rename from ios/web/public/web_state/global_web_state_observer.h
rename to ios/web/public/deprecated/global_web_state_observer.h
index 4d74dfad..1e234601 100644
--- a/ios/web/public/web_state/global_web_state_observer.h
+++ b/ios/web/public/deprecated/global_web_state_observer.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 IOS_WEB_PUBLIC_WEB_STATE_GLOBAL_WEB_STATE_OBSERVER_H_
-#define IOS_WEB_PUBLIC_WEB_STATE_GLOBAL_WEB_STATE_OBSERVER_H_
+#ifndef IOS_WEB_PUBLIC_DEPRECATED_GLOBAL_WEB_STATE_OBSERVER_H_
+#define IOS_WEB_PUBLIC_DEPRECATED_GLOBAL_WEB_STATE_OBSERVER_H_
 
 #include <stddef.h>
 
@@ -64,4 +64,4 @@
 
 }  // namespace web
 
-#endif  // IOS_WEB_PUBLIC_WEB_STATE_GLOBAL_WEB_STATE_OBSERVER_H_
+#endif  // IOS_WEB_PUBLIC_DEPRECATED_GLOBAL_WEB_STATE_OBSERVER_H_
diff --git a/ios/web/public/navigation_item_list.h b/ios/web/public/deprecated/navigation_item_list.h
similarity index 81%
rename from ios/web/public/navigation_item_list.h
rename to ios/web/public/deprecated/navigation_item_list.h
index c922a13..f691242 100644
--- a/ios/web/public/navigation_item_list.h
+++ b/ios/web/public/deprecated/navigation_item_list.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 IOS_WEB_PUBLIC_NAVIGATION_ITEM_LIST_H_
-#define IOS_WEB_PUBLIC_NAVIGATION_ITEM_LIST_H_
+#ifndef IOS_WEB_PUBLIC_DEPRECATED_NAVIGATION_ITEM_LIST_H_
+#define IOS_WEB_PUBLIC_DEPRECATED_NAVIGATION_ITEM_LIST_H_
 
 #include <memory>
 #include <vector>
@@ -26,4 +26,4 @@
 
 }  // namespace web
 
-#endif  // IOS_WEB_PUBLIC_NAVIGATION_ITEM_LIST_H_
+#endif  // IOS_WEB_PUBLIC_DEPRECATED_NAVIGATION_ITEM_LIST_H_
diff --git a/ios/web/public/navigation_item_list.mm b/ios/web/public/deprecated/navigation_item_list.mm
similarity index 90%
rename from ios/web/public/navigation_item_list.mm
rename to ios/web/public/deprecated/navigation_item_list.mm
index 18f837c..e23be158 100644
--- a/ios/web/public/navigation_item_list.mm
+++ b/ios/web/public/deprecated/navigation_item_list.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/web/public/navigation_item_list.h"
+#import "ios/web/public/deprecated/navigation_item_list.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
diff --git a/ios/web/public/test/fakes/test_native_content.h b/ios/web/public/deprecated/test_native_content.h
similarity index 68%
rename from ios/web/public/test/fakes/test_native_content.h
rename to ios/web/public/deprecated/test_native_content.h
index 230c089..3b895dc 100644
--- a/ios/web/public/test/fakes/test_native_content.h
+++ b/ios/web/public/deprecated/test_native_content.h
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_WEB_PUBLIC_TEST_FAKES_TEST_NATIVE_CONTENT_H_
-#define IOS_WEB_PUBLIC_TEST_FAKES_TEST_NATIVE_CONTENT_H_
+#ifndef IOS_WEB_PUBLIC_DEPRECATED_TEST_NATIVE_CONTENT_H_
+#define IOS_WEB_PUBLIC_DEPRECATED_TEST_NATIVE_CONTENT_H_
 
-#import "ios/web/public/web_state/ui/crw_native_content.h"
+#import "ios/web/public/deprecated/crw_native_content.h"
 
 // A test class that implement CRWNativeContent.
-@interface TestNativeContent : NSObject<CRWNativeContent>
+@interface TestNativeContent : NSObject <CRWNativeContent>
 // Inits the CRWNativeContent.
 // |URL| will be returned by the |url| method of the object.
 // If |virtualURL| is valid, it will be returned by the |virtualURL| method.
@@ -19,4 +19,4 @@
 - (instancetype)init NS_UNAVAILABLE;
 @end
 
-#endif  // IOS_WEB_PUBLIC_TEST_FAKES_TEST_NATIVE_CONTENT_H_
+#endif  // IOS_WEB_PUBLIC_DEPRECATED_TEST_NATIVE_CONTENT_H_
diff --git a/ios/web/public/test/fakes/test_native_content.mm b/ios/web/public/deprecated/test_native_content.mm
similarity index 94%
rename from ios/web/public/test/fakes/test_native_content.mm
rename to ios/web/public/deprecated/test_native_content.mm
index ec6f21a..11374873 100644
--- a/ios/web/public/test/fakes/test_native_content.mm
+++ b/ios/web/public/deprecated/test_native_content.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/web/public/test/fakes/test_native_content.h"
+#import "ios/web/public/deprecated/test_native_content.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
diff --git a/ios/web/public/deprecated/test_native_content_provider.h b/ios/web/public/deprecated/test_native_content_provider.h
new file mode 100644
index 0000000..0e3dbd9
--- /dev/null
+++ b/ios/web/public/deprecated/test_native_content_provider.h
@@ -0,0 +1,20 @@
+// Copyright 2016 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.
+
+#ifndef IOS_WEB_PUBLIC_DEPRECATED_TEST_NATIVE_CONTENT_PROVIDER_H_
+#define IOS_WEB_PUBLIC_DEPRECATED_TEST_NATIVE_CONTENT_PROVIDER_H_
+
+#import "ios/web/public/deprecated/crw_native_content_provider.h"
+
+@protocol CRWNativeContent;
+
+// A test class that will return CRWNativeContent for specified URLs.
+@interface TestNativeContentProvider : NSObject <CRWNativeContentProvider>
+
+// Add a |CRWNativeContent| for |URL|.
+- (void)setController:(id<CRWNativeContent>)controller forURL:(const GURL&)URL;
+
+@end
+
+#endif  // IOS_WEB_PUBLIC_DEPRECATED_TEST_NATIVE_CONTENT_PROVIDER_H_
diff --git a/ios/web/public/test/fakes/test_native_content_provider.mm b/ios/web/public/deprecated/test_native_content_provider.mm
similarity index 94%
rename from ios/web/public/test/fakes/test_native_content_provider.mm
rename to ios/web/public/deprecated/test_native_content_provider.mm
index ad116ce..446fb54 100644
--- a/ios/web/public/test/fakes/test_native_content_provider.mm
+++ b/ios/web/public/deprecated/test_native_content_provider.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/web/public/test/fakes/test_native_content_provider.h"
+#import "ios/web/public/deprecated/test_native_content_provider.h"
 
 #include <map>
 
diff --git a/ios/web/public/web_state/url_verification_constants.h b/ios/web/public/deprecated/url_verification_constants.h
similarity index 69%
rename from ios/web/public/web_state/url_verification_constants.h
rename to ios/web/public/deprecated/url_verification_constants.h
index f973d56..fdd5e635 100644
--- a/ios/web/public/web_state/url_verification_constants.h
+++ b/ios/web/public/deprecated/url_verification_constants.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 IOS_WEB_PUBLIC_WEB_STATE_URL_VERIFICATION_CONSTANTS_H_
-#define IOS_WEB_PUBLIC_WEB_STATE_URL_VERIFICATION_CONSTANTS_H_
+#ifndef IOS_WEB_PUBLIC_DEPRECATED_URL_VERIFICATION_CONSTANTS_H_
+#define IOS_WEB_PUBLIC_DEPRECATED_URL_VERIFICATION_CONSTANTS_H_
 
 namespace web {
 enum URLVerificationTrustLevel {
@@ -17,4 +17,4 @@
 };
 }  // namespace web
 
-#endif  // IOS_WEB_PUBLIC_WEB_STATE_URL_VERIFICATION_CONSTANTS_H_
+#endif  // IOS_WEB_PUBLIC_DEPRECATED_URL_VERIFICATION_CONSTANTS_H_
diff --git a/ios/web/public/navigation_manager.h b/ios/web/public/navigation_manager.h
index 2bd607f6..c43ab9b 100644
--- a/ios/web/public/navigation_manager.h
+++ b/ios/web/public/navigation_manager.h
@@ -9,7 +9,7 @@
 
 #include "base/callback.h"
 #include "ios/web/public/browser_url_rewriter.h"
-#include "ios/web/public/navigation_item_list.h"
+#include "ios/web/public/deprecated/navigation_item_list.h"
 #include "ios/web/public/referrer.h"
 #include "ios/web/public/reload_type.h"
 #include "ios/web/public/user_agent.h"
diff --git a/ios/web/public/test/BUILD.gn b/ios/web/public/test/BUILD.gn
index 7d03bab..58666c50 100644
--- a/ios/web/public/test/BUILD.gn
+++ b/ios/web/public/test/BUILD.gn
@@ -17,6 +17,7 @@
     "//ios/web:web",
     "//ios/web/navigation",
     "//ios/web/navigation:wk_navigation_util",
+    "//ios/web/public/deprecated",
     "//ios/web/test:test_support",
     "//testing/gtest",
     "//ui/base",
@@ -65,6 +66,7 @@
     "//base",
     "//base/test:test_support",
     "//ios/web/public:public",
+    "//ios/web/public/deprecated",
     "//ios/web/web_state:web_state_impl_header",
     "//ios/web/web_state/js:script_util",
     "//ios/web/web_state/ui:ui",
diff --git a/ios/web/public/test/earl_grey/js_test_util.mm b/ios/web/public/test/earl_grey/js_test_util.mm
index 1ec5bb5..88496e5 100644
--- a/ios/web/public/test/earl_grey/js_test_util.mm
+++ b/ios/web/public/test/earl_grey/js_test_util.mm
@@ -9,7 +9,7 @@
 #import "base/test/ios/wait_util.h"
 #include "base/timer/elapsed_timer.h"
 #import "ios/testing/earl_grey/earl_grey_app.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #import "ios/web/security/web_interstitial_impl.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/web/public/test/fakes/BUILD.gn b/ios/web/public/test/fakes/BUILD.gn
index 490c4aa1..9b17bb5 100644
--- a/ios/web/public/test/fakes/BUILD.gn
+++ b/ios/web/public/test/fakes/BUILD.gn
@@ -11,6 +11,7 @@
     "//ios/web/common",
     "//ios/web/js_messaging",
     "//ios/web/navigation:core",
+    "//ios/web/public/deprecated",
     "//ios/web/public/download",
     "//ios/web/public/find_in_page",
     "//ios/web/public/js_messaging",
@@ -34,8 +35,6 @@
     "crw_fake_find_in_page_manager_delegate.mm",
     "crw_fake_web_state_policy_decider.h",
     "crw_fake_web_state_policy_decider.mm",
-    "crw_test_js_injection_receiver.h",
-    "crw_test_js_injection_receiver.mm",
     "crw_test_web_state_observer.h",
     "crw_test_web_state_observer.mm",
     "fake_download_controller_delegate.h",
@@ -54,10 +53,6 @@
     "test_browser_state.h",
     "test_java_script_dialog_presenter.h",
     "test_java_script_dialog_presenter.mm",
-    "test_native_content.h",
-    "test_native_content.mm",
-    "test_native_content_provider.h",
-    "test_native_content_provider.mm",
     "test_navigation_manager.h",
     "test_navigation_manager.mm",
     "test_web_client.h",
diff --git a/ios/web/public/test/fakes/crw_test_js_injection_receiver.h b/ios/web/public/test/fakes/crw_test_js_injection_receiver.h
deleted file mode 100644
index 4f36f973..0000000
--- a/ios/web/public/test/fakes/crw_test_js_injection_receiver.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_WEB_PUBLIC_TEST_FAKES_CRW_TEST_JS_INJECTION_RECEIVER_H_
-#define IOS_WEB_PUBLIC_TEST_FAKES_CRW_TEST_JS_INJECTION_RECEIVER_H_
-
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
-
-// TestInjectionReceiver is used for tests.
-// It uses a bare UIWebView as backend for javascript evaluation.
-@interface CRWTestJSInjectionReceiver : CRWJSInjectionReceiver
-@end
-
-#endif  // IOS_WEB_PUBLIC_TEST_FAKES_CRW_TEST_JS_INJECTION_RECEIVER_H_
diff --git a/ios/web/public/test/fakes/test_native_content_provider.h b/ios/web/public/test/fakes/test_native_content_provider.h
deleted file mode 100644
index 00f838cd..0000000
--- a/ios/web/public/test/fakes/test_native_content_provider.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2016 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.
-
-#ifndef IOS_WEB_PUBLIC_TEST_FAKES_TEST_NATIVE_CONTENT_PROVIDER_H_
-#define IOS_WEB_PUBLIC_TEST_FAKES_TEST_NATIVE_CONTENT_PROVIDER_H_
-
-#import "ios/web/public/web_state/ui/crw_native_content_provider.h"
-
-@protocol CRWNativeContent;
-
-// A test class that will return CRWNativeContent for specified URLs.
-@interface TestNativeContentProvider : NSObject<CRWNativeContentProvider>
-
-// Add a |CRWNativeContent| for |URL|.
-- (void)setController:(id<CRWNativeContent>)controller forURL:(const GURL&)URL;
-
-@end
-
-#endif  // IOS_WEB_PUBLIC_TEST_FAKES_TEST_NATIVE_CONTENT_PROVIDER_H_
diff --git a/ios/web/public/test/fakes/test_navigation_manager.h b/ios/web/public/test/fakes/test_navigation_manager.h
index b94aade..981d06f 100644
--- a/ios/web/public/test/fakes/test_navigation_manager.h
+++ b/ios/web/public/test/fakes/test_navigation_manager.h
@@ -6,8 +6,8 @@
 #define IOS_WEB_PUBLIC_TEST_FAKES_TEST_NAVIGATION_MANAGER_H_
 
 #include "base/callback.h"
+#include "ios/web/public/deprecated/navigation_item_list.h"
 #import "ios/web/public/navigation_item.h"
-#include "ios/web/public/navigation_item_list.h"
 #import "ios/web/public/navigation_manager.h"
 #include "ui/base/page_transition_types.h"
 
diff --git a/ios/web/public/test/fakes/test_web_state.h b/ios/web/public/test/fakes/test_web_state.h
index e8d2831..8bbb67c3 100644
--- a/ios/web/public/test/fakes/test_web_state.h
+++ b/ios/web/public/test/fakes/test_web_state.h
@@ -12,8 +12,8 @@
 
 #include "base/observer_list.h"
 #include "base/strings/string16.h"
+#include "ios/web/public/deprecated/url_verification_constants.h"
 #import "ios/web/public/navigation_manager.h"
-#include "ios/web/public/web_state/url_verification_constants.h"
 #import "ios/web/public/web_state/web_state.h"
 #include "ios/web/public/web_state/web_state_observer.h"
 #import "ios/web/public/web_state/web_state_policy_decider.h"
diff --git a/ios/web/public/test/js_test_util.mm b/ios/web/public/test/js_test_util.mm
index 5cc897e..ea3b7ceb 100644
--- a/ios/web/public/test/js_test_util.mm
+++ b/ios/web/public/test/js_test_util.mm
@@ -10,8 +10,8 @@
 #include "base/mac/bundle_locations.h"
 #include "base/strings/sys_string_conversions.h"
 #import "base/test/ios/wait_util.h"
-#import "ios/web/public/web_state/js/crw_js_injection_manager.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
+#import "ios/web/public/deprecated/crw_js_injection_manager.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #import "ios/web/web_state/js/page_script_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/ios/web/public/test/native_controller_test_util.mm b/ios/web/public/test/native_controller_test_util.mm
index b3eaa8d..3919ddb2 100644
--- a/ios/web/public/test/native_controller_test_util.mm
+++ b/ios/web/public/test/native_controller_test_util.mm
@@ -4,7 +4,7 @@
 
 #import "ios/web/public/test/native_controller_test_util.h"
 
-#import "ios/web/public/web_state/ui/crw_native_content_holder.h"
+#import "ios/web/public/deprecated/crw_native_content_holder.h"
 #import "ios/web/web_state/ui/crw_web_controller.h"
 #import "ios/web/web_state/web_state_impl.h"
 
diff --git a/ios/web/public/test/web_test.mm b/ios/web/public/test/web_test.mm
index 0ae3b936..85c1f72 100644
--- a/ios/web/public/test/web_test.mm
+++ b/ios/web/public/test/web_test.mm
@@ -5,7 +5,7 @@
 #include "ios/web/public/test/web_test.h"
 
 #include "base/memory/ptr_util.h"
-#include "ios/web/public/web_state/global_web_state_observer.h"
+#include "ios/web/public/deprecated/global_web_state_observer.h"
 #import "ios/web/public/test/fakes/test_web_client.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/web/public/test/web_test_with_web_state.mm b/ios/web/public/test/web_test_with_web_state.mm
index 900f3b8..6a480ec3 100644
--- a/ios/web/public/test/web_test_with_web_state.mm
+++ b/ios/web/public/test/web_test_with_web_state.mm
@@ -13,8 +13,8 @@
 #import "ios/web/navigation/crw_wk_navigation_states.h"
 #import "ios/web/navigation/navigation_manager_impl.h"
 #import "ios/web/navigation/wk_navigation_util.h"
+#include "ios/web/public/deprecated/url_verification_constants.h"
 #import "ios/web/public/web_client.h"
-#include "ios/web/public/web_state/url_verification_constants.h"
 #include "ios/web/public/web_state/web_state_observer.h"
 #import "ios/web/web_state/ui/crw_js_injector.h"
 #import "ios/web/web_state/ui/crw_web_controller.h"
diff --git a/ios/web/public/web_state/web_state.h b/ios/web/public/web_state/web_state.h
index ecb5194..11b7b92b 100644
--- a/ios/web/public/web_state/web_state.h
+++ b/ios/web/public/web_state/web_state.h
@@ -15,8 +15,8 @@
 #include "base/callback_forward.h"
 #include "base/memory/weak_ptr.h"
 #include "base/supports_user_data.h"
+#include "ios/web/public/deprecated/url_verification_constants.h"
 #include "ios/web/public/referrer.h"
-#include "ios/web/public/web_state/url_verification_constants.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
 #include "mojo/public/cpp/system/message_pipe.h"
 #include "ui/base/page_transition_types.h"
diff --git a/ios/web/shell/test/BUILD.gn b/ios/web/shell/test/BUILD.gn
index 952f354c..64f2a70 100644
--- a/ios/web/shell/test/BUILD.gn
+++ b/ios/web/shell/test/BUILD.gn
@@ -10,8 +10,8 @@
   testonly = true
   deps = [
     ":ios_web_shell_eg2tests",
+    ":ios_web_shell_eg2tests_module",
     ":ios_web_shell_egtests",
-    ":ios_web_shell_test_app_host",
   ]
 }
 
@@ -212,7 +212,7 @@
   libs = [ "UIKit.framework" ]
 }
 
-ios_eg2_test_app_host("ios_web_shell_test_app_host") {
+ios_eg2_test_app_host("ios_web_shell_eg2tests") {
   info_plist = "//ios/web/shell/Info.plist"
 
   deps = [
@@ -224,8 +224,8 @@
   ]
 }
 
-ios_eg2_test("ios_web_shell_eg2tests") {
-  xcode_test_application_name = "ios_web_shell_test_app_host"
+ios_eg2_test("ios_web_shell_eg2tests_module") {
+  xcode_test_application_name = "ios_web_shell_eg2tests"
 
   deps = [
     # Test support libraries.
diff --git a/ios/web/web_state/BUILD.gn b/ios/web/web_state/BUILD.gn
index 14e37689..e08e345 100644
--- a/ios/web/web_state/BUILD.gn
+++ b/ios/web/web_state/BUILD.gn
@@ -14,6 +14,7 @@
     "//ios/web/navigation:core",
     "//ios/web/navigation:wk_navigation_util",
     "//ios/web/public",
+    "//ios/web/public/deprecated",
     "//ios/web/public/session",
     "//ios/web/security",
     "//ios/web/security",
diff --git a/ios/web/web_state/global_web_state_event_tracker.h b/ios/web/web_state/global_web_state_event_tracker.h
index 1cff14c..001ef85 100644
--- a/ios/web/web_state/global_web_state_event_tracker.h
+++ b/ios/web/web_state/global_web_state_event_tracker.h
@@ -11,7 +11,7 @@
 #include "base/no_destructor.h"
 #include "base/observer_list.h"
 #include "base/scoped_observer.h"
-#include "ios/web/public/web_state/global_web_state_observer.h"
+#include "ios/web/public/deprecated/global_web_state_observer.h"
 #include "ios/web/public/web_state/web_state_observer.h"
 
 namespace web {
diff --git a/ios/web/web_state/global_web_state_observer.cc b/ios/web/web_state/global_web_state_observer.cc
index c8cb004..efda7b7 100644
--- a/ios/web/web_state/global_web_state_observer.cc
+++ b/ios/web/web_state/global_web_state_observer.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 "ios/web/public/web_state/global_web_state_observer.h"
+#include "ios/web/public/deprecated/global_web_state_observer.h"
 
 #include "ios/web/web_state/global_web_state_event_tracker.h"
 
diff --git a/ios/web/web_state/js/BUILD.gn b/ios/web/web_state/js/BUILD.gn
index 28b6271..0d9490c 100644
--- a/ios/web/web_state/js/BUILD.gn
+++ b/ios/web/web_state/js/BUILD.gn
@@ -9,6 +9,7 @@
     ":script_util",
     "//base",
     "//ios/web/public",
+    "//ios/web/public/deprecated",
   ]
 
   sources = [
diff --git a/ios/web/web_state/js/crw_js_injection_manager.mm b/ios/web/web_state/js/crw_js_injection_manager.mm
index 960fcfa..5a1a83be 100644
--- a/ios/web/web_state/js/crw_js_injection_manager.mm
+++ b/ios/web/web_state/js/crw_js_injection_manager.mm
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/web/public/web_state/js/crw_js_injection_manager.h"
+#import "ios/web/public/deprecated/crw_js_injection_manager.h"
 
 #import <UIKit/UIKit.h>
 
 #include "base/logging.h"
 #include "base/mac/bundle_locations.h"
 #include "base/strings/sys_string_conversions.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #import "ios/web/web_state/js/page_script_util.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/web/web_state/js/crw_js_injection_manager_unittest.mm b/ios/web/web_state/js/crw_js_injection_manager_unittest.mm
index 81ef710..6f9d2a7 100644
--- a/ios/web/web_state/js/crw_js_injection_manager_unittest.mm
+++ b/ios/web/web_state/js/crw_js_injection_manager_unittest.mm
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/web/public/web_state/js/crw_js_injection_manager.h"
+#import "ios/web/public/deprecated/crw_js_injection_manager.h"
 
-#include <stddef.h>
 #import <Foundation/Foundation.h>
+#include <stddef.h>
 
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #import "ios/web/public/test/web_test_with_web_state.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
 #import "ios/web/public/web_state/web_state.h"
 #import "testing/gtest_mac.h"
 
diff --git a/ios/web/web_state/js/crw_js_injection_receiver.mm b/ios/web/web_state/js/crw_js_injection_receiver.mm
index 8b74208..8d71b4d 100644
--- a/ios/web/web_state/js/crw_js_injection_receiver.mm
+++ b/ios/web/web_state/js/crw_js_injection_receiver.mm
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 
 #include "base/logging.h"
-#import "ios/web/public/web_state/js/crw_js_injection_evaluator.h"
-#import "ios/web/public/web_state/js/crw_js_injection_manager.h"
+#import "ios/web/public/deprecated/crw_js_injection_evaluator.h"
+#import "ios/web/public/deprecated/crw_js_injection_manager.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
diff --git a/ios/web/web_state/ui/BUILD.gn b/ios/web/web_state/ui/BUILD.gn
index 8b90330..2c2da60 100644
--- a/ios/web/web_state/ui/BUILD.gn
+++ b/ios/web/web_state/ui/BUILD.gn
@@ -24,6 +24,7 @@
     "//ios/web/navigation:wk_navigation_util",
     "//ios/web/net:net",
     "//ios/web/public",
+    "//ios/web/public/deprecated",
     "//ios/web/public/download",
     "//ios/web/public/js_messaging",
     "//ios/web/public/security",
@@ -101,6 +102,7 @@
   deps = [
     "//base",
     "//ios/web/public",
+    "//ios/web/public/deprecated",
     "//ios/web/web_state:context_menu",
     "//ios/web/web_state/ui:crw_wk_script_message_router",
     "//ios/web/web_state/ui:wk_web_view_configuration_provider",
diff --git a/ios/web/web_state/ui/controller/BUILD.gn b/ios/web/web_state/ui/controller/BUILD.gn
index dcfdbca4..ebb6a6ee 100644
--- a/ios/web/web_state/ui/controller/BUILD.gn
+++ b/ios/web/web_state/ui/controller/BUILD.gn
@@ -13,6 +13,7 @@
     "//ios/web/navigation:core",
     "//ios/web/net",
     "//ios/web/public",
+    "//ios/web/public/deprecated",
     "//ios/web/web_state:web_state_impl_header",
     "//ui/base",
     "//url",
diff --git a/ios/web/web_state/ui/controller/crw_legacy_native_content_controller.h b/ios/web/web_state/ui/controller/crw_legacy_native_content_controller.h
index f81c354..040facd8 100644
--- a/ios/web/web_state/ui/controller/crw_legacy_native_content_controller.h
+++ b/ios/web/web_state/ui/controller/crw_legacy_native_content_controller.h
@@ -7,7 +7,7 @@
 
 #include <UIKit/UIKit.h>
 
-#import "ios/web/public/web_state/ui/crw_native_content_holder.h"
+#import "ios/web/public/deprecated/crw_native_content_holder.h"
 
 namespace web {
 class NavigationContextImpl;
diff --git a/ios/web/web_state/ui/controller/crw_legacy_native_content_controller.mm b/ios/web/web_state/ui/controller/crw_legacy_native_content_controller.mm
index 538695a..3728959 100644
--- a/ios/web/web_state/ui/controller/crw_legacy_native_content_controller.mm
+++ b/ios/web/web_state/ui/controller/crw_legacy_native_content_controller.mm
@@ -8,10 +8,10 @@
 #include "base/strings/sys_string_conversions.h"
 #import "ios/web/navigation/navigation_context_impl.h"
 #import "ios/web/navigation/navigation_item_impl.h"
+#import "ios/web/public/deprecated/crw_native_content.h"
+#import "ios/web/public/deprecated/crw_native_content_provider.h"
 #import "ios/web/public/navigation_item.h"
 #import "ios/web/public/web_client.h"
-#import "ios/web/public/web_state/ui/crw_native_content.h"
-#import "ios/web/public/web_state/ui/crw_native_content_provider.h"
 #import "ios/web/web_state/ui/controller/crw_legacy_native_content_controller_delegate.h"
 #import "ios/web/web_state/web_state_impl.h"
 #include "url/gurl.h"
diff --git a/ios/web/web_state/ui/crw_context_menu_controller.mm b/ios/web/web_state/ui/crw_context_menu_controller.mm
index 3e6c2e2..4e2f31b 100644
--- a/ios/web/web_state/ui/crw_context_menu_controller.mm
+++ b/ios/web/web_state/ui/crw_context_menu_controller.mm
@@ -13,8 +13,8 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/unguessable_token.h"
+#import "ios/web/public/deprecated/crw_context_menu_delegate.h"
 #import "ios/web/public/web_state/context_menu_params.h"
-#import "ios/web/public/web_state/ui/crw_context_menu_delegate.h"
 #import "ios/web/web_state/context_menu_constants.h"
 #import "ios/web/web_state/context_menu_params_utils.h"
 #import "ios/web/web_state/ui/crw_wk_script_message_router.h"
diff --git a/ios/web/web_state/ui/crw_js_injector.h b/ios/web/web_state/ui/crw_js_injector.h
index 9781a6d..f6bb527 100644
--- a/ios/web/web_state/ui/crw_js_injector.h
+++ b/ios/web/web_state/ui/crw_js_injector.h
@@ -7,7 +7,7 @@
 
 #import <UIKit/UIKit.h>
 
-#import "ios/web/public/web_state/js/crw_js_injection_evaluator.h"
+#import "ios/web/public/deprecated/crw_js_injection_evaluator.h"
 #include "url/gurl.h"
 
 @class CRWJSInjectionReceiver;
diff --git a/ios/web/web_state/ui/crw_js_injector.mm b/ios/web/web_state/ui/crw_js_injector.mm
index 4024749..9adc4b3 100644
--- a/ios/web/web_state/ui/crw_js_injector.mm
+++ b/ios/web/web_state/ui/crw_js_injector.mm
@@ -7,9 +7,9 @@
 #import <WebKit/WebKit.h>
 
 #include "base/logging.h"
+#import "ios/web/public/deprecated/crw_js_injection_manager.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #import "ios/web/public/web_client.h"
-#import "ios/web/public/web_state/js/crw_js_injection_manager.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
 #import "ios/web/web_state/js/crw_js_window_id_manager.h"
 #import "ios/web/web_state/ui/web_view_js_utils.h"
 
diff --git a/ios/web/web_state/ui/crw_web_controller.h b/ios/web/web_state/ui/crw_web_controller.h
index f91f9e28..53f7f9fd5 100644
--- a/ios/web/web_state/ui/crw_web_controller.h
+++ b/ios/web/web_state/ui/crw_web_controller.h
@@ -8,7 +8,7 @@
 #import <UIKit/UIKit.h>
 
 #import "ios/web/navigation/crw_session_controller.h"
-#include "ios/web/public/web_state/url_verification_constants.h"
+#include "ios/web/public/deprecated/url_verification_constants.h"
 #import "ios/web/public/web_state/web_state.h"
 #import "ios/web/web_state/ui/crw_touch_tracking_recognizer.h"
 #import "ios/web/web_state/ui/crw_web_view_navigation_proxy.h"
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm
index 43f669e..b453f93e 100644
--- a/ios/web/web_state/ui/crw_web_controller.mm
+++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -67,6 +67,10 @@
 #import "ios/web/navigation/wk_navigation_action_util.h"
 #import "ios/web/navigation/wk_navigation_util.h"
 #include "ios/web/public/browser_state.h"
+#import "ios/web/public/deprecated/crw_context_menu_delegate.h"
+#import "ios/web/public/deprecated/crw_native_content.h"
+#import "ios/web/public/deprecated/crw_native_content_provider.h"
+#include "ios/web/public/deprecated/url_verification_constants.h"
 #import "ios/web/public/download/download_controller.h"
 #include "ios/web/public/favicon_url.h"
 #import "ios/web/public/java_script_dialog_presenter.h"
@@ -80,11 +84,7 @@
 #import "ios/web/public/web_client.h"
 #import "ios/web/public/web_state/context_menu_params.h"
 #import "ios/web/public/web_state/page_display_state.h"
-#import "ios/web/public/web_state/ui/crw_context_menu_delegate.h"
-#import "ios/web/public/web_state/ui/crw_native_content.h"
-#import "ios/web/public/web_state/ui/crw_native_content_provider.h"
 #import "ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h"
-#include "ios/web/public/web_state/url_verification_constants.h"
 #import "ios/web/public/web_state/web_state.h"
 #import "ios/web/public/web_state/web_state_policy_decider.h"
 #include "ios/web/public/webui/web_ui_ios.h"
diff --git a/ios/web/web_state/ui/crw_web_controller_container_view.mm b/ios/web/web_state/ui/crw_web_controller_container_view.mm
index 6b2ff9eb..cf5c8c3 100644
--- a/ios/web/web_state/ui/crw_web_controller_container_view.mm
+++ b/ios/web/web_state/ui/crw_web_controller_container_view.mm
@@ -8,8 +8,8 @@
 #import "ios/web/common/crw_content_view.h"
 #import "ios/web/common/crw_web_view_content_view.h"
 #include "ios/web/common/features.h"
-#import "ios/web/public/web_state/ui/crw_native_content.h"
-#import "ios/web/public/web_state/ui/crw_native_content_holder.h"
+#import "ios/web/public/deprecated/crw_native_content.h"
+#import "ios/web/public/deprecated/crw_native_content_holder.h"
 #import "ios/web/web_state/ui/crw_web_view_proxy_impl.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/web/web_state/ui/crw_web_controller_unittest.mm b/ios/web/web_state/ui/crw_web_controller_unittest.mm
index bf852a42..f73d668 100644
--- a/ios/web/web_state/ui/crw_web_controller_unittest.mm
+++ b/ios/web/web_state/ui/crw_web_controller_unittest.mm
@@ -24,6 +24,13 @@
 #import "ios/web/navigation/navigation_item_impl.h"
 #import "ios/web/navigation/navigation_manager_impl.h"
 #import "ios/web/navigation/wk_navigation_action_policy_util.h"
+
+#import "ios/web/public/deprecated/crw_native_content.h"
+#import "ios/web/public/deprecated/crw_native_content_holder.h"
+#import "ios/web/public/deprecated/crw_native_content_provider.h"
+#import "ios/web/public/deprecated/test_native_content.h"
+#import "ios/web/public/deprecated/test_native_content_provider.h"
+#include "ios/web/public/deprecated/url_verification_constants.h"
 #import "ios/web/public/download/download_controller.h"
 #import "ios/web/public/download/download_task.h"
 #include "ios/web/public/referrer.h"
@@ -32,17 +39,11 @@
 #include "ios/web/public/test/fakes/fake_download_controller_delegate.h"
 #import "ios/web/public/test/fakes/fake_web_state_policy_decider.h"
 #include "ios/web/public/test/fakes/test_browser_state.h"
-#import "ios/web/public/test/fakes/test_native_content.h"
-#import "ios/web/public/test/fakes/test_native_content_provider.h"
 #import "ios/web/public/test/fakes/test_web_client.h"
 #import "ios/web/public/test/fakes/test_web_state_delegate.h"
 #include "ios/web/public/test/fakes/test_web_state_observer.h"
 #import "ios/web/public/test/fakes/test_web_view_content_view.h"
 #import "ios/web/public/test/web_view_content_test_util.h"
-#import "ios/web/public/web_state/ui/crw_native_content.h"
-#import "ios/web/public/web_state/ui/crw_native_content_holder.h"
-#import "ios/web/public/web_state/ui/crw_native_content_provider.h"
-#include "ios/web/public/web_state/url_verification_constants.h"
 #include "ios/web/public/web_state/web_state_observer.h"
 #import "ios/web/security/wk_web_view_security_util.h"
 #import "ios/web/test/fakes/crw_fake_back_forward_list.h"
diff --git a/ios/web/web_state/web_state_impl.mm b/ios/web/web_state/web_state_impl.mm
index f669cdd..e90a491 100644
--- a/ios/web/web_state/web_state_impl.mm
+++ b/ios/web/web_state/web_state_impl.mm
@@ -23,6 +23,8 @@
 #import "ios/web/navigation/wk_based_navigation_manager_impl.h"
 #import "ios/web/navigation/wk_navigation_util.h"
 #include "ios/web/public/browser_state.h"
+#import "ios/web/public/deprecated/crw_native_content.h"
+#import "ios/web/public/deprecated/crw_native_content_holder.h"
 #include "ios/web/public/favicon_url.h"
 #import "ios/web/public/java_script_dialog_presenter.h"
 #import "ios/web/public/navigation_item.h"
@@ -31,8 +33,6 @@
 #import "ios/web/public/session/serializable_user_data_manager.h"
 #import "ios/web/public/web_client.h"
 #import "ios/web/public/web_state/context_menu_params.h"
-#import "ios/web/public/web_state/ui/crw_native_content.h"
-#import "ios/web/public/web_state/ui/crw_native_content_holder.h"
 #import "ios/web/public/web_state/web_state_delegate.h"
 #include "ios/web/public/web_state/web_state_interface_provider.h"
 #include "ios/web/public/web_state/web_state_observer.h"
diff --git a/ios/web/web_state/web_state_impl_unittest.mm b/ios/web/web_state/web_state_impl_unittest.mm
index 8fa8cab6..bf9ea272 100644
--- a/ios/web/web_state/web_state_impl_unittest.mm
+++ b/ios/web/web_state/web_state_impl_unittest.mm
@@ -22,6 +22,7 @@
 #import "ios/web/navigation/navigation_item_impl.h"
 #import "ios/web/navigation/serializable_user_data_manager_impl.h"
 #import "ios/web/navigation/wk_navigation_util.h"
+#include "ios/web/public/deprecated/global_web_state_observer.h"
 #import "ios/web/public/java_script_dialog_presenter.h"
 #import "ios/web/public/session/crw_navigation_item_storage.h"
 #import "ios/web/public/session/crw_session_storage.h"
@@ -33,7 +34,6 @@
 #import "ios/web/public/test/fakes/test_web_state_observer.h"
 #include "ios/web/public/test/web_test.h"
 #import "ios/web/public/web_state/context_menu_params.h"
-#include "ios/web/public/web_state/global_web_state_observer.h"
 #import "ios/web/public/web_state/web_state_delegate.h"
 #include "ios/web/public/web_state/web_state_observer.h"
 #import "ios/web/public/web_state/web_state_policy_decider.h"
diff --git a/ios/web/web_state/web_state_observer_inttest.mm b/ios/web/web_state/web_state_observer_inttest.mm
index cae0a28..359dbb2ec 100644
--- a/ios/web/web_state/web_state_observer_inttest.mm
+++ b/ios/web/web_state/web_state_observer_inttest.mm
@@ -19,19 +19,19 @@
 #include "ios/web/common/features.h"
 #include "ios/web/navigation/web_kit_constants.h"
 #include "ios/web/navigation/wk_navigation_util.h"
+#import "ios/web/public/deprecated/crw_native_content_holder.h"
+#import "ios/web/public/deprecated/test_native_content.h"
+#import "ios/web/public/deprecated/test_native_content_provider.h"
 #import "ios/web/public/navigation_item.h"
 #import "ios/web/public/navigation_manager.h"
 #import "ios/web/public/session/crw_navigation_item_storage.h"
 #import "ios/web/public/session/crw_session_storage.h"
-#import "ios/web/public/test/fakes/test_native_content.h"
-#import "ios/web/public/test/fakes/test_native_content_provider.h"
 #include "ios/web/public/test/fakes/test_web_state_observer.h"
 #import "ios/web/public/test/navigation_test_util.h"
 #import "ios/web/public/test/web_view_content_test_util.h"
 #import "ios/web/public/test/web_view_interaction_test_util.h"
 #import "ios/web/public/web_client.h"
 #import "ios/web/public/web_state/navigation_context.h"
-#import "ios/web/public/web_state/ui/crw_native_content_holder.h"
 #include "ios/web/public/web_state/web_state_observer.h"
 #import "ios/web/public/web_state/web_state_policy_decider.h"
 #include "ios/web/test/test_url_constants.h"
diff --git a/ios/web_view/BUILD.gn b/ios/web_view/BUILD.gn
index 0cb4452c..edd7dcf4 100644
--- a/ios/web_view/BUILD.gn
+++ b/ios/web_view/BUILD.gn
@@ -309,6 +309,7 @@
   "//ios/web/common",
   "//ios/web/public",
   "//ios/web/public/app",
+  "//ios/web/public/deprecated",
   "//ios/web/public/security",
   "//ios/web/public/js_messaging",
   "//ios/web/public/global_state",
@@ -432,10 +433,10 @@
     "//components/signin/core/browser:internals_test_support",
     "//components/signin/ios/browser:test_support",
     "//components/sync:test_support",
+    "//ios/web/public/deprecated:test_doubles",
     "//ios/web/public/js_messaging",
     "//ios/web/public/security",
     "//ios/web/public/test",
-    "//ios/web/public/test/fakes",
     "//services/identity/public/cpp:test_support",
     "//testing/gtest",
     "//third_party/ocmock",
diff --git a/ios/web_view/internal/autofill/cwv_autofill_controller.mm b/ios/web_view/internal/autofill/cwv_autofill_controller.mm
index 7b91e67..c886a6d 100644
--- a/ios/web_view/internal/autofill/cwv_autofill_controller.mm
+++ b/ios/web_view/internal/autofill/cwv_autofill_controller.mm
@@ -24,10 +24,10 @@
 #include "components/autofill/ios/form_util/form_activity_params.h"
 #include "components/keyed_service/core/service_access_type.h"
 #include "components/sync/driver/sync_service.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #include "ios/web/public/js_messaging/web_frame.h"
 #include "ios/web/public/js_messaging/web_frame_util.h"
 #import "ios/web/public/js_messaging/web_frames_manager.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
 #import "ios/web/public/web_state/web_state_observer_bridge.h"
 #include "ios/web_view/internal/app/application_context.h"
 #import "ios/web_view/internal/autofill/cwv_autofill_client_ios_bridge.h"
diff --git a/ios/web_view/internal/autofill/cwv_autofill_controller_unittest.mm b/ios/web_view/internal/autofill/cwv_autofill_controller_unittest.mm
index 7237aa4..bb2f116 100644
--- a/ios/web_view/internal/autofill/cwv_autofill_controller_unittest.mm
+++ b/ios/web_view/internal/autofill/cwv_autofill_controller_unittest.mm
@@ -19,8 +19,8 @@
 #include "components/autofill/ios/form_util/form_activity_params.h"
 #import "components/autofill/ios/form_util/form_activity_tab_helper.h"
 #import "components/autofill/ios/form_util/test_form_activity_tab_helper.h"
+#import "ios/web/public/deprecated/crw_test_js_injection_receiver.h"
 #include "ios/web/public/js_messaging/web_frames_manager.h"
-#import "ios/web/public/test/fakes/crw_test_js_injection_receiver.h"
 #import "ios/web/public/test/fakes/fake_web_frame.h"
 #import "ios/web/public/test/fakes/test_web_state.h"
 #include "ios/web/public/test/test_web_thread_bundle.h"
diff --git a/ios/web_view/internal/cwv_web_view.mm b/ios/web_view/internal/cwv_web_view.mm
index 70fad8a..9647a6f 100644
--- a/ios/web_view/internal/cwv_web_view.mm
+++ b/ios/web_view/internal/cwv_web_view.mm
@@ -16,6 +16,7 @@
 #import "components/autofill/ios/browser/js_suggestion_manager.h"
 #include "components/language/ios/browser/ios_language_detection_tab_helper.h"
 #include "google_apis/google_api_keys.h"
+#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
 #include "ios/web/public/favicon_url.h"
 #import "ios/web/public/js_messaging/web_frames_manager.h"
 #import "ios/web/public/navigation_item.h"
@@ -24,7 +25,6 @@
 #include "ios/web/public/reload_type.h"
 #import "ios/web/public/web_client.h"
 #import "ios/web/public/web_state/context_menu_params.h"
-#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
 #import "ios/web/public/web_state/navigation_context.h"
 #import "ios/web/public/web_state/ui/crw_web_view_proxy.h"
 #import "ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h"
diff --git a/ios/web_view/internal/translate/cwv_translation_controller_unittest.mm b/ios/web_view/internal/translate/cwv_translation_controller_unittest.mm
index fa49278e..a05f267 100644
--- a/ios/web_view/internal/translate/cwv_translation_controller_unittest.mm
+++ b/ios/web_view/internal/translate/cwv_translation_controller_unittest.mm
@@ -11,7 +11,7 @@
 #include "base/strings/sys_string_conversions.h"
 #include "components/language/ios/browser/ios_language_detection_tab_helper.h"
 #include "components/translate/core/browser/translate_prefs.h"
-#import "ios/web/public/test/fakes/crw_test_js_injection_receiver.h"
+#import "ios/web/public/deprecated/crw_test_js_injection_receiver.h"
 #import "ios/web/public/test/fakes/test_navigation_manager.h"
 #import "ios/web/public/test/fakes/test_web_state.h"
 #include "ios/web/public/test/test_web_thread_bundle.h"
diff --git a/media/blink/watch_time_reporter.cc b/media/blink/watch_time_reporter.cc
index 1579edc3..317826da 100644
--- a/media/blink/watch_time_reporter.cc
+++ b/media/blink/watch_time_reporter.cc
@@ -350,14 +350,20 @@
   // TODO(dalecurtis): We should only consider |volume_| when there is actually
   // an audio track; requires updating lots of tests to fix.
   return ShouldReportWatchTime() && is_playing_ && volume_ && is_visible_ &&
-         !in_shutdown_ && !is_seeking_;
+         !in_shutdown_ && !is_seeking_ && has_valid_start_timestamp_;
 }
 
 void WatchTimeReporter::MaybeStartReportingTimer(
     base::TimeDelta start_timestamp) {
-  DCHECK_NE(start_timestamp, kInfiniteDuration);
   DCHECK_GE(start_timestamp, base::TimeDelta());
 
+  // It's possible for |current_time| to be kInfiniteDuration here if the page
+  // seeks to kInfiniteDuration (2**64 - 1) when Duration() is infinite. There
+  // is no possible elapsed watch time when this occurs, so don't start the
+  // WatchTimeReporter at this time. If a later seek puts us earlier in the
+  // stream this method will be called again after OnSeeking().
+  has_valid_start_timestamp_ = start_timestamp != kInfiniteDuration;
+
   // Don't start the timer if our state indicates we shouldn't; this check is
   // important since the various event handlers do not have to care about the
   // state of other events.
diff --git a/media/blink/watch_time_reporter.h b/media/blink/watch_time_reporter.h
index 021f76c..eb143af 100644
--- a/media/blink/watch_time_reporter.h
+++ b/media/blink/watch_time_reporter.h
@@ -213,6 +213,7 @@
   bool is_visible_ = true;
   bool is_seeking_ = false;
   bool in_shutdown_ = false;
+  bool has_valid_start_timestamp_ = false;
   double volume_ = 1.0;
 
   // Updated by UpdateSecondaryProperties(); controls timer state when
diff --git a/media/blink/watch_time_reporter_unittest.cc b/media/blink/watch_time_reporter_unittest.cc
index 06d2a05..2c99e30 100644
--- a/media/blink/watch_time_reporter_unittest.cc
+++ b/media/blink/watch_time_reporter_unittest.cc
@@ -659,6 +659,14 @@
   wtr_.reset();
 }
 
+TEST_P(WatchTimeReporterTest, WatchTimeReporterInfiniteStartTime) {
+  EXPECT_CALL(*this, GetCurrentMediaTime())
+      .WillRepeatedly(testing::Return(kInfiniteDuration));
+  Initialize(false, false, kSizeJustRight);
+  wtr_->OnPlaying();
+  EXPECT_FALSE(IsMonitoring());
+}
+
 TEST_P(WatchTimeReporterTest, WatchTimeReporterBasic) {
   constexpr base::TimeDelta kWatchTimeEarly = base::TimeDelta::FromSeconds(5);
   constexpr base::TimeDelta kWatchTimeLate = base::TimeDelta::FromSeconds(10);
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc
index f52b52ff..76a53ab 100644
--- a/media/blink/webmediaplayer_impl.cc
+++ b/media/blink/webmediaplayer_impl.cc
@@ -1863,11 +1863,12 @@
   CreateWatchTimeReporter();
   CreateVideoDecodeStatsReporter();
 
-  UpdatePlayState();
-
-  // This may trigger all sorts of calls into this class (e.g., Play(), Pause())
-  // so do it last to avoid unexpected states during the calls.
+  // SetReadyState() may trigger all sorts of calls into this class (e.g.,
+  // Play(), Pause(), etc) so do it last to avoid unexpected states during the
+  // calls. An exception to this is UpdatePlayState(), which is safe to call and
+  // needs to use the new ReadyState in its calculations.
   SetReadyState(WebMediaPlayer::kReadyStateHaveMetadata);
+  UpdatePlayState();
 }
 
 void WebMediaPlayerImpl::ActivateSurfaceLayerForVideo() {
diff --git a/media/gpu/vaapi/BUILD.gn b/media/gpu/vaapi/BUILD.gn
index 0786d501..2bac145bb 100644
--- a/media/gpu/vaapi/BUILD.gn
+++ b/media/gpu/vaapi/BUILD.gn
@@ -80,6 +80,7 @@
     "//media/gpu:common",
     "//media/gpu:video_frame_mapper_common",
     "//media/gpu/linux",
+    "//media/parsers",
     "//mojo/public/cpp/bindings",
     "//third_party/libyuv",
     "//ui/gfx",
@@ -97,7 +98,6 @@
     deps += [
       "//components/chromeos_camera:jpeg_encode_accelerator",
       "//components/chromeos_camera:mjpeg_decode_accelerator",
-      "//media/parsers",
     ]
   }
 
diff --git a/net/BUILD.gn b/net/BUILD.gn
index 95a8409..830129d 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -3180,6 +3180,8 @@
 
   executable("epoll_quic_server") {
     sources = [
+      "third_party/quiche/src/quic/tools/quic_epoll_server_factory.cc",
+      "third_party/quiche/src/quic/tools/quic_epoll_server_factory.h",
       "third_party/quiche/src/quic/tools/quic_server_bin.cc",
       "third_party/quiche/src/quic/tools/quic_toy_server.cc",
       "third_party/quiche/src/quic/tools/quic_toy_server.h",
diff --git a/net/base/network_change_notifier_win.cc b/net/base/network_change_notifier_win.cc
index ac47d3c..44336d6 100644
--- a/net/base/network_change_notifier_win.cc
+++ b/net/base/network_change_notifier_win.cc
@@ -294,11 +294,14 @@
 bool NetworkChangeNotifierWin::WatchForAddressChangeInternal() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  dns_config_service_runner_->PostTask(
-      FROM_HERE, base::BindOnce(&DnsConfigService::WatchConfig,
-                                base::Unretained(dns_config_service_.get()),
-                                base::BindRepeating(
-                                    &NetworkChangeNotifier::SetDnsConfig)));
+  if (!posted_watch_config_) {
+    posted_watch_config_ = true;
+    dns_config_service_runner_->PostTask(
+        FROM_HERE, base::BindOnce(&DnsConfigService::WatchConfig,
+                                  base::Unretained(dns_config_service_.get()),
+                                  base::BindRepeating(
+                                      &NetworkChangeNotifier::SetDnsConfig)));
+  }
 
   ResetEventIfSignaled(addr_overlapped_.hEvent);
   HANDLE handle = nullptr;
diff --git a/net/base/network_change_notifier_win.h b/net/base/network_change_notifier_win.h
index 533c90ac..e7a00b9c 100644
--- a/net/base/network_change_notifier_win.h
+++ b/net/base/network_change_notifier_win.h
@@ -124,6 +124,9 @@
   // Number of times polled to check if still offline.
   int offline_polls_;
 
+  // Keeps track of whether DnsConfigService::WatchConfig() has been called.
+  bool posted_watch_config_ = false;
+
   SEQUENCE_CHECKER(sequence_checker_);
 
   // Used for calling WatchForAddressChange again on failure.
diff --git a/net/http/http_stream_factory_unittest.cc b/net/http/http_stream_factory_unittest.cc
index ac5eacc..9258f8f 100644
--- a/net/http/http_stream_factory_unittest.cc
+++ b/net/http/http_stream_factory_unittest.cc
@@ -2293,7 +2293,7 @@
 INSTANTIATE_TEST_SUITE_P(
     VersionIncludeStreamDependencySequence,
     HttpStreamFactoryBidirectionalQuicTest,
-    ::testing::Combine(::testing::ValuesIn(quic::AllSupportedVersions()),
+    ::testing::Combine(::testing::ValuesIn(quic::AllVersionsExcept99()),
                        ::testing::Bool()));
 
 TEST_P(HttpStreamFactoryBidirectionalQuicTest,
diff --git a/net/quic/bidirectional_stream_quic_impl_unittest.cc b/net/quic/bidirectional_stream_quic_impl_unittest.cc
index 4ee06cc..3256fa844 100644
--- a/net/quic/bidirectional_stream_quic_impl_unittest.cc
+++ b/net/quic/bidirectional_stream_quic_impl_unittest.cc
@@ -868,7 +868,7 @@
 INSTANTIATE_TEST_SUITE_P(
     Version,
     BidirectionalStreamQuicImplTest,
-    ::testing::Combine(::testing::ValuesIn(quic::AllSupportedVersions()),
+    ::testing::Combine(::testing::ValuesIn(quic::AllVersionsExcept99()),
                        ::testing::Bool()));
 
 TEST_P(BidirectionalStreamQuicImplTest, GetRequest) {
diff --git a/net/quic/platform/impl/quic_test_impl.cc b/net/quic/platform/impl/quic_test_impl.cc
index f1c3c06..a7e57370 100644
--- a/net/quic/platform/impl/quic_test_impl.cc
+++ b/net/quic/platform/impl/quic_test_impl.cc
@@ -27,3 +27,15 @@
   // The file path is known to be an ascii string.
   return path.MaybeAsASCII();
 }
+
+namespace quic {
+ParsedQuicVersionVector AllVersionsExcept99() {
+  ParsedQuicVersionVector result;
+  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
+    if (version.transport_version != QUIC_VERSION_99) {
+      result.push_back(version);
+    }
+  }
+  return result;
+}
+}  // namespace quic
diff --git a/net/quic/platform/impl/quic_test_impl.h b/net/quic/platform/impl/quic_test_impl.h
index 0e89786..72f2485 100644
--- a/net/quic/platform/impl/quic_test_impl.h
+++ b/net/quic/platform/impl/quic_test_impl.h
@@ -7,6 +7,7 @@
 
 #include "base/logging.h"
 #include "net/test/test_with_scoped_task_environment.h"
+#include "net/third_party/quiche/src/quic/core/quic_versions.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
 #include "testing/gmock/include/gmock/gmock.h"      // IWYU pragma: export
 #include "testing/gtest/include/gtest/gtest-spi.h"  // IWYU pragma: export
@@ -66,4 +67,14 @@
 
 std::string QuicGetTestMemoryCachePathImpl();
 
+namespace quic {
+// A utility function that returns all versions except v99.  Intended to be a
+// drop-in replacement for quic::AllSupportedVersion() when disabling v99 in a
+// large test file is required.
+//
+// TODO(vasilvv): all of the tests should be fixed for v99, so that this
+// function can be removed.
+ParsedQuicVersionVector AllVersionsExcept99();
+}  // namespace quic
+
 #endif  // NET_QUIC_PLATFORM_IMPL_QUIC_TEST_IMPL_H_
diff --git a/net/quic/quic_chromium_client_session.cc b/net/quic/quic_chromium_client_session.cc
index 579e769e..ca1f360 100644
--- a/net/quic/quic_chromium_client_session.cc
+++ b/net/quic/quic_chromium_client_session.cc
@@ -1439,11 +1439,9 @@
     quic::QuicStreamOffset bytes_written) {
   if (quic::QuicUtils::IsServerInitiatedStreamId(
           connection()->transport_version(), id)) {
-    StreamHandler handler = GetOrCreateStreamImpl(id);
-    if (handler.is_pending) {
-      bytes_pushed_count_ += handler.pending->stream_bytes_read();
-    } else if (handler.stream) {
-      bytes_pushed_count_ += handler.stream->stream_bytes_read();
+    quic::QuicStream* stream = GetOrCreateStream(id);
+    if (stream) {
+      bytes_pushed_count_ += stream->stream_bytes_read();
     }
   }
 
diff --git a/net/quic/quic_chromium_client_stream_test.cc b/net/quic/quic_chromium_client_stream_test.cc
index 90ee9828..7fc2ffe 100644
--- a/net/quic/quic_chromium_client_stream_test.cc
+++ b/net/quic/quic_chromium_client_stream_test.cc
@@ -544,6 +544,11 @@
 }
 
 TEST_P(QuicChromiumClientStreamTest, OnTrailers) {
+  // TODO(vasilvv): reenable this for v99.
+  if (GetParam() == quic::QUIC_VERSION_99) {
+    return;
+  }
+
   InitializeHeaders();
   ProcessHeadersFull(headers_);
 
@@ -596,6 +601,11 @@
 // Tests that trailers are marked as consumed only before delegate is to be
 // immediately notified about trailers.
 TEST_P(QuicChromiumClientStreamTest, MarkTrailersConsumedWhenNotifyDelegate) {
+  // TODO(vasilvv): reenable this for v99.
+  if (GetParam() == quic::QUIC_VERSION_99) {
+    return;
+  }
+
   InitializeHeaders();
   ProcessHeadersFull(headers_);
 
@@ -655,6 +665,11 @@
 // are received but not yet delivered, Read() will return ERR_IO_PENDING instead
 // of 0 (EOF).
 TEST_P(QuicChromiumClientStreamTest, ReadAfterTrailersReceivedButNotDelivered) {
+  // TODO(vasilvv): reenable this for v99.
+  if (GetParam() == quic::QUIC_VERSION_99) {
+    return;
+  }
+
   InitializeHeaders();
   ProcessHeadersFull(headers_);
 
diff --git a/net/quic/quic_http_stream_test.cc b/net/quic/quic_http_stream_test.cc
index 781b0a4..5138485 100644
--- a/net/quic/quic_http_stream_test.cc
+++ b/net/quic/quic_http_stream_test.cc
@@ -730,7 +730,7 @@
 INSTANTIATE_TEST_SUITE_P(
     VersionIncludeStreamDependencySequence,
     QuicHttpStreamTest,
-    ::testing::Combine(::testing::ValuesIn(quic::AllSupportedVersions()),
+    ::testing::Combine(::testing::ValuesIn(quic::AllVersionsExcept99()),
                        ::testing::Bool()));
 
 TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
diff --git a/net/quic/quic_network_transaction_unittest.cc b/net/quic/quic_network_transaction_unittest.cc
index fa3dbbf6..ca519c5d 100644
--- a/net/quic/quic_network_transaction_unittest.cc
+++ b/net/quic/quic_network_transaction_unittest.cc
@@ -157,7 +157,7 @@
 std::vector<PoolingTestParams> GetPoolingTestParams() {
   std::vector<PoolingTestParams> params;
   quic::ParsedQuicVersionVector all_supported_versions =
-      quic::AllSupportedVersions();
+      quic::AllVersionsExcept99();
   for (const quic::ParsedQuicVersion version : all_supported_versions) {
     params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
     params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
@@ -1008,7 +1008,7 @@
 INSTANTIATE_TEST_SUITE_P(
     VersionIncludeStreamDependencySequence,
     QuicNetworkTransactionTest,
-    ::testing::Combine(::testing::ValuesIn(quic::AllSupportedVersions()),
+    ::testing::Combine(::testing::ValuesIn(quic::AllVersionsExcept99()),
                        ::testing::Bool()));
 
 TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
diff --git a/net/quic/quic_proxy_client_socket_unittest.cc b/net/quic/quic_proxy_client_socket_unittest.cc
index 9c1edbe..9f3b438 100644
--- a/net/quic/quic_proxy_client_socket_unittest.cc
+++ b/net/quic/quic_proxy_client_socket_unittest.cc
@@ -1807,7 +1807,7 @@
 INSTANTIATE_TEST_SUITE_P(
     VersionIncludeStreamDependencySequence,
     QuicProxyClientSocketTest,
-    ::testing::Combine(::testing::ValuesIn(quic::AllSupportedVersions()),
+    ::testing::Combine(::testing::ValuesIn(quic::AllVersionsExcept99()),
                        ::testing::Bool()));
 
 }  // namespace test
diff --git a/net/quic/quic_stream_factory_test.cc b/net/quic/quic_stream_factory_test.cc
index 2a26bc8..4c90979 100644
--- a/net/quic/quic_stream_factory_test.cc
+++ b/net/quic/quic_stream_factory_test.cc
@@ -132,7 +132,7 @@
 std::vector<TestParams> GetTestParams() {
   std::vector<TestParams> params;
   quic::ParsedQuicVersionVector all_supported_versions =
-      quic::AllSupportedVersions();
+      quic::AllVersionsExcept99();
   for (const auto& version : all_supported_versions) {
     params.push_back(TestParams{version, false});
     params.push_back(TestParams{version, true});
@@ -172,7 +172,7 @@
 std::vector<PoolingTestParams> GetPoolingTestParams() {
   std::vector<PoolingTestParams> params;
   quic::ParsedQuicVersionVector all_supported_versions =
-      quic::AllSupportedVersions();
+      quic::AllVersionsExcept99();
   for (const quic::ParsedQuicVersion version : all_supported_versions) {
     params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
     params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
diff --git a/sandbox/win/src/handle_closer_agent.cc b/sandbox/win/src/handle_closer_agent.cc
index 5a91155c..65410b19 100644
--- a/sandbox/win/src/handle_closer_agent.cc
+++ b/sandbox/win/src/handle_closer_agent.cc
@@ -66,24 +66,61 @@
   DCHECK(dummy_handle_.Get() != closed_handle);
 
   std::vector<HANDLE> to_close;
-  HANDLE dup_dummy = nullptr;
-  size_t count = 16;
+
+  const DWORD original_proc_num = GetCurrentProcessorNumber();
+  DWORD proc_num = original_proc_num;
+  DWORD_PTR original_affinity_mask =
+      SetThreadAffinityMask(GetCurrentThread(), DWORD_PTR{1} << proc_num);
+  bool found_handle = false;
+  BOOL result = FALSE;
+
+  // There is per-processor based free list of handles entries. The free handle
+  // from current processor's freelist is preferred for reusing, so cycling
+  // through all possible processors to find closed_handle.
+  // Start searching from current processor which covers usual cases.
 
   do {
-    if (!::DuplicateHandle(::GetCurrentProcess(), dummy_handle_.Get(),
-                           ::GetCurrentProcess(), &dup_dummy, 0, false, 0))
+    DWORD_PTR current_mask = DWORD_PTR{1} << proc_num;
+
+    if (original_affinity_mask & current_mask) {
+      if (proc_num != original_proc_num) {
+        SetThreadAffinityMask(GetCurrentThread(), current_mask);
+      }
+
+      HANDLE dup_dummy = nullptr;
+      size_t count = 16;
+
+      do {
+        result =
+            ::DuplicateHandle(::GetCurrentProcess(), dummy_handle_.Get(),
+                              ::GetCurrentProcess(), &dup_dummy, 0, false, 0);
+        if (!result) {
+          break;
+        }
+        if (dup_dummy != closed_handle) {
+          to_close.push_back(dup_dummy);
+        } else {
+          found_handle = true;
+        }
+      } while (count-- && reinterpret_cast<uintptr_t>(dup_dummy) <
+                              reinterpret_cast<uintptr_t>(closed_handle));
+    }
+
+    proc_num++;
+    if (proc_num == sizeof(DWORD_PTR) * 8) {
+      proc_num = 0;
+    }
+    if (proc_num == original_proc_num) {
       break;
-    if (dup_dummy != closed_handle)
-      to_close.push_back(dup_dummy);
-  } while (count-- && reinterpret_cast<uintptr_t>(dup_dummy) <
-                          reinterpret_cast<uintptr_t>(closed_handle));
+    }
+  } while (result && !found_handle);
+
+  SetThreadAffinityMask(GetCurrentThread(), original_affinity_mask);
 
   for (HANDLE h : to_close)
     ::CloseHandle(h);
 
-  // TODO(wfh): Investigate why stuffing handles sometimes fails.
-  // http://crbug.com/649904
-  return dup_dummy == closed_handle;
+  return found_handle;
 }
 
 // Reads g_handles_to_close and creates the lookup map.
diff --git a/services/service_manager/sandbox/win/sandbox_win.cc b/services/service_manager/sandbox/win/sandbox_win.cc
index 779a153..b5e74f45 100644
--- a/services/service_manager/sandbox/win/sandbox_win.cc
+++ b/services/service_manager/sandbox/win/sandbox_win.cc
@@ -102,9 +102,11 @@
     L"mdnsnsp.dll",                // Bonjour.
     L"moonsysh.dll",               // Moon Secure Antivirus.
     L"mpk.dll",                    // KGB Spy.
+    L"n64hooks.dll",               // Neilsen//NetRatings NetSight.
     L"npdivx32.dll",               // DivX.
     L"npggNT.des",                 // GameGuard 2008.
     L"npggNT.dll",                 // GameGuard (older).
+    L"nphooks.dll",                // Neilsen//NetRatings NetSight.
     L"oawatch.dll",                // Online Armor.
     L"pastali32.dll",              // PastaLeads.
     L"pavhook.dll",                // Panda Internet Security.
diff --git a/services/services_strings.grd b/services/services_strings.grd
new file mode 100644
index 0000000..dd8670b
--- /dev/null
+++ b/services/services_strings.grd
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+This file contains strings for code in //services.
+-->
+
+<grit base_dir="." latest_public_release="0" current_release="1"
+      output_all_resource_defines="false" source_lang_id="en" enc_check="möl">
+  <outputs>
+    <output filename="grit/services_strings.h" type="rc_header">
+      <emit emit_type="prepend"></emit>
+    </output>
+    <output filename="services_strings_am.pak" type="data_package" lang="am" />
+    <output filename="services_strings_ar.pak" type="data_package" lang="ar" />
+    <output filename="services_strings_bg.pak" type="data_package" lang="bg" />
+    <output filename="services_strings_bn.pak" type="data_package" lang="bn" />
+    <output filename="services_strings_ca.pak" type="data_package" lang="ca" />
+    <output filename="services_strings_cs.pak" type="data_package" lang="cs" />
+    <output filename="services_strings_da.pak" type="data_package" lang="da" />
+    <output filename="services_strings_de.pak" type="data_package" lang="de" />
+    <output filename="services_strings_el.pak" type="data_package" lang="el" />
+    <output filename="services_strings_en-GB.pak" type="data_package" lang="en-GB" />
+    <output filename="services_strings_en-US.pak" type="data_package" lang="en" />
+    <output filename="services_strings_es.pak" type="data_package" lang="es" />
+    <output filename="services_strings_es-419.pak" type="data_package" lang="es-419" />
+    <output filename="services_strings_et.pak" type="data_package" lang="et" />
+    <output filename="services_strings_fa.pak" type="data_package" lang="fa" />
+    <output filename="services_strings_fake-bidi.pak" type="data_package" lang="fake-bidi" />
+    <output filename="services_strings_fi.pak" type="data_package" lang="fi" />
+    <output filename="services_strings_fil.pak" type="data_package" lang="fil" />
+    <output filename="services_strings_fr.pak" type="data_package" lang="fr" />
+    <output filename="services_strings_gu.pak" type="data_package" lang="gu" />
+    <output filename="services_strings_he.pak" type="data_package" lang="he" />
+    <output filename="services_strings_hi.pak" type="data_package" lang="hi" />
+    <output filename="services_strings_hr.pak" type="data_package" lang="hr" />
+    <output filename="services_strings_hu.pak" type="data_package" lang="hu" />
+    <output filename="services_strings_id.pak" type="data_package" lang="id" />
+    <output filename="services_strings_it.pak" type="data_package" lang="it" />
+    <output filename="services_strings_ja.pak" type="data_package" lang="ja" />
+    <output filename="services_strings_kn.pak" type="data_package" lang="kn" />
+    <output filename="services_strings_ko.pak" type="data_package" lang="ko" />
+    <output filename="services_strings_lt.pak" type="data_package" lang="lt" />
+    <output filename="services_strings_lv.pak" type="data_package" lang="lv" />
+    <output filename="services_strings_ml.pak" type="data_package" lang="ml" />
+    <output filename="services_strings_mr.pak" type="data_package" lang="mr" />
+    <output filename="services_strings_ms.pak" type="data_package" lang="ms" />
+    <output filename="services_strings_nl.pak" type="data_package" lang="nl" />
+    <!-- The translation console uses 'no' for Norwegian Bokmål. It should
+         be 'nb'. -->
+    <output filename="services_strings_nb.pak" type="data_package" lang="no" />
+    <output filename="services_strings_pl.pak" type="data_package" lang="pl" />
+    <output filename="services_strings_pt-BR.pak" type="data_package" lang="pt-BR" />
+    <output filename="services_strings_pt-PT.pak" type="data_package" lang="pt-PT" />
+    <output filename="services_strings_ro.pak" type="data_package" lang="ro" />
+    <output filename="services_strings_ru.pak" type="data_package" lang="ru" />
+    <output filename="services_strings_sk.pak" type="data_package" lang="sk" />
+    <output filename="services_strings_sl.pak" type="data_package" lang="sl" />
+    <output filename="services_strings_sr.pak" type="data_package" lang="sr" />
+    <output filename="services_strings_sv.pak" type="data_package" lang="sv" />
+    <output filename="services_strings_sw.pak" type="data_package" lang="sw" />
+    <output filename="services_strings_ta.pak" type="data_package" lang="ta" />
+    <output filename="services_strings_te.pak" type="data_package" lang="te" />
+    <output filename="services_strings_th.pak" type="data_package" lang="th" />
+    <output filename="services_strings_tr.pak" type="data_package" lang="tr" />
+    <output filename="services_strings_uk.pak" type="data_package" lang="uk" />
+    <output filename="services_strings_vi.pak" type="data_package" lang="vi" />
+    <output filename="services_strings_zh-CN.pak" type="data_package" lang="zh-CN" />
+    <output filename="services_strings_zh-TW.pak" type="data_package" lang="zh-TW" />
+  </outputs>
+  <translations>
+    <file path="strings/services_strings_am.xtb" lang="am" />
+    <file path="strings/services_strings_ar.xtb" lang="ar" />
+    <file path="strings/services_strings_bg.xtb" lang="bg" />
+    <file path="strings/services_strings_bn.xtb" lang="bn" />
+    <file path="strings/services_strings_ca.xtb" lang="ca" />
+    <file path="strings/services_strings_cs.xtb" lang="cs" />
+    <file path="strings/services_strings_da.xtb" lang="da" />
+    <file path="strings/services_strings_de.xtb" lang="de" />
+    <file path="strings/services_strings_el.xtb" lang="el" />
+    <file path="strings/services_strings_en-GB.xtb" lang="en-GB" />
+    <file path="strings/services_strings_es.xtb" lang="es" />
+    <file path="strings/services_strings_es-419.xtb" lang="es-419" />
+    <file path="strings/services_strings_et.xtb" lang="et" />
+    <file path="strings/services_strings_fa.xtb" lang="fa" />
+    <file path="strings/services_strings_fi.xtb" lang="fi" />
+    <file path="strings/services_strings_fil.xtb" lang="fil" />
+    <file path="strings/services_strings_fr.xtb" lang="fr" />
+    <file path="strings/services_strings_gu.xtb" lang="gu" />
+    <file path="strings/services_strings_hi.xtb" lang="hi" />
+    <file path="strings/services_strings_hr.xtb" lang="hr" />
+    <file path="strings/services_strings_hu.xtb" lang="hu" />
+    <file path="strings/services_strings_id.xtb" lang="id" />
+    <file path="strings/services_strings_it.xtb" lang="it" />
+    <!-- The translation console uses 'iw' for Hebrew, but we use 'he'. -->
+    <file path="strings/services_strings_iw.xtb" lang="he" />
+    <file path="strings/services_strings_ja.xtb" lang="ja" />
+    <file path="strings/services_strings_kn.xtb" lang="kn" />
+    <file path="strings/services_strings_ko.xtb" lang="ko" />
+    <file path="strings/services_strings_lt.xtb" lang="lt" />
+    <file path="strings/services_strings_lv.xtb" lang="lv" />
+    <file path="strings/services_strings_ml.xtb" lang="ml" />
+    <file path="strings/services_strings_mr.xtb" lang="mr" />
+    <file path="strings/services_strings_ms.xtb" lang="ms" />
+    <file path="strings/services_strings_nl.xtb" lang="nl" />
+    <file path="strings/services_strings_no.xtb" lang="no" />
+    <file path="strings/services_strings_pl.xtb" lang="pl" />
+    <file path="strings/services_strings_pt-BR.xtb" lang="pt-BR" />
+    <file path="strings/services_strings_pt-PT.xtb" lang="pt-PT" />
+    <file path="strings/services_strings_ro.xtb" lang="ro" />
+    <file path="strings/services_strings_ru.xtb" lang="ru" />
+    <file path="strings/services_strings_sk.xtb" lang="sk" />
+    <file path="strings/services_strings_sl.xtb" lang="sl" />
+    <file path="strings/services_strings_sr.xtb" lang="sr" />
+    <file path="strings/services_strings_sv.xtb" lang="sv" />
+    <file path="strings/services_strings_sw.xtb" lang="sw" />
+    <file path="strings/services_strings_ta.xtb" lang="ta" />
+    <file path="strings/services_strings_te.xtb" lang="te" />
+    <file path="strings/services_strings_th.xtb" lang="th" />
+    <file path="strings/services_strings_tr.xtb" lang="tr" />
+    <file path="strings/services_strings_uk.xtb" lang="uk" />
+    <file path="strings/services_strings_vi.xtb" lang="vi" />
+    <file path="strings/services_strings_zh-CN.xtb" lang="zh-CN" />
+    <file path="strings/services_strings_zh-TW.xtb" lang="zh-TW" />
+  </translations>
+  <release seq="1" allow_pseudo="false">
+    <messages fallback_to_english="true">
+      <message name="IDS_PROXY_RESOLVER_DISPLAY_NAME" desc="The name of the display name (in system task manager, etc) of the service process used for out-of-process V8 proxy resolution.">
+        V8 Proxy Resolver
+      </message>
+    </messages>
+  </release>
+</grit>
diff --git a/services/strings/BUILD.gn b/services/strings/BUILD.gn
new file mode 100644
index 0000000..e760d4e
--- /dev/null
+++ b/services/strings/BUILD.gn
@@ -0,0 +1,66 @@
+# Copyright 2019 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.
+
+import("//tools/grit/grit_rule.gni")
+
+grit("strings") {
+  source = "../services_strings.grd"
+  outputs = [
+    "grit/services_strings.h",
+    "services_strings_am.pak",
+    "services_strings_ar.pak",
+    "services_strings_bg.pak",
+    "services_strings_bn.pak",
+    "services_strings_ca.pak",
+    "services_strings_cs.pak",
+    "services_strings_da.pak",
+    "services_strings_de.pak",
+    "services_strings_el.pak",
+    "services_strings_en-GB.pak",
+    "services_strings_en-US.pak",
+    "services_strings_es.pak",
+    "services_strings_es-419.pak",
+    "services_strings_et.pak",
+    "services_strings_fa.pak",
+    "services_strings_fake-bidi.pak",
+    "services_strings_fi.pak",
+    "services_strings_fil.pak",
+    "services_strings_fr.pak",
+    "services_strings_gu.pak",
+    "services_strings_he.pak",
+    "services_strings_hi.pak",
+    "services_strings_hr.pak",
+    "services_strings_hu.pak",
+    "services_strings_id.pak",
+    "services_strings_it.pak",
+    "services_strings_ja.pak",
+    "services_strings_kn.pak",
+    "services_strings_ko.pak",
+    "services_strings_lt.pak",
+    "services_strings_lv.pak",
+    "services_strings_ml.pak",
+    "services_strings_mr.pak",
+    "services_strings_ms.pak",
+    "services_strings_nl.pak",
+    "services_strings_nb.pak",
+    "services_strings_pl.pak",
+    "services_strings_pt-BR.pak",
+    "services_strings_pt-PT.pak",
+    "services_strings_ro.pak",
+    "services_strings_ru.pak",
+    "services_strings_sk.pak",
+    "services_strings_sl.pak",
+    "services_strings_sr.pak",
+    "services_strings_sv.pak",
+    "services_strings_sw.pak",
+    "services_strings_ta.pak",
+    "services_strings_te.pak",
+    "services_strings_th.pak",
+    "services_strings_tr.pak",
+    "services_strings_uk.pak",
+    "services_strings_vi.pak",
+    "services_strings_zh-CN.pak",
+    "services_strings_zh-TW.pak",
+  ]
+}
diff --git a/services/strings/services_strings_am.xtb b/services/strings/services_strings_am.xtb
new file mode 100644
index 0000000..b0d50467
--- /dev/null
+++ b/services/strings/services_strings_am.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="am"></translationbundle>
diff --git a/services/strings/services_strings_ar.xtb b/services/strings/services_strings_ar.xtb
new file mode 100644
index 0000000..af627ab9
--- /dev/null
+++ b/services/strings/services_strings_ar.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="ar"></translationbundle>
diff --git a/services/strings/services_strings_bg.xtb b/services/strings/services_strings_bg.xtb
new file mode 100644
index 0000000..4ae1b0a
--- /dev/null
+++ b/services/strings/services_strings_bg.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="bg"></translationbundle>
diff --git a/services/strings/services_strings_bn.xtb b/services/strings/services_strings_bn.xtb
new file mode 100644
index 0000000..288c5166
--- /dev/null
+++ b/services/strings/services_strings_bn.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="bn"></translationbundle>
diff --git a/services/strings/services_strings_ca.xtb b/services/strings/services_strings_ca.xtb
new file mode 100644
index 0000000..8aac7a9
--- /dev/null
+++ b/services/strings/services_strings_ca.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="ca"></translationbundle>
diff --git a/services/strings/services_strings_cs.xtb b/services/strings/services_strings_cs.xtb
new file mode 100644
index 0000000..7585cf0
--- /dev/null
+++ b/services/strings/services_strings_cs.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="cs"></translationbundle>
diff --git a/services/strings/services_strings_da.xtb b/services/strings/services_strings_da.xtb
new file mode 100644
index 0000000..b91c935d
--- /dev/null
+++ b/services/strings/services_strings_da.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="da"></translationbundle>
diff --git a/services/strings/services_strings_de.xtb b/services/strings/services_strings_de.xtb
new file mode 100644
index 0000000..8cba06d
--- /dev/null
+++ b/services/strings/services_strings_de.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="de"></translationbundle>
diff --git a/services/strings/services_strings_el.xtb b/services/strings/services_strings_el.xtb
new file mode 100644
index 0000000..672e997
--- /dev/null
+++ b/services/strings/services_strings_el.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="el"></translationbundle>
diff --git a/services/strings/services_strings_en-GB.xtb b/services/strings/services_strings_en-GB.xtb
new file mode 100644
index 0000000..3eb8cba2
--- /dev/null
+++ b/services/strings/services_strings_en-GB.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="en-GB"></translationbundle>
diff --git a/services/strings/services_strings_es-419.xtb b/services/strings/services_strings_es-419.xtb
new file mode 100644
index 0000000..64491be
--- /dev/null
+++ b/services/strings/services_strings_es-419.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="es-419"></translationbundle>
diff --git a/services/strings/services_strings_es.xtb b/services/strings/services_strings_es.xtb
new file mode 100644
index 0000000..226abad2
--- /dev/null
+++ b/services/strings/services_strings_es.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="es"></translationbundle>
diff --git a/services/strings/services_strings_et.xtb b/services/strings/services_strings_et.xtb
new file mode 100644
index 0000000..ce235003
--- /dev/null
+++ b/services/strings/services_strings_et.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="et"></translationbundle>
diff --git a/services/strings/services_strings_fa.xtb b/services/strings/services_strings_fa.xtb
new file mode 100644
index 0000000..4514f808
--- /dev/null
+++ b/services/strings/services_strings_fa.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="fa"></translationbundle>
diff --git a/services/strings/services_strings_fi.xtb b/services/strings/services_strings_fi.xtb
new file mode 100644
index 0000000..aeca9fa
--- /dev/null
+++ b/services/strings/services_strings_fi.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="fi"></translationbundle>
diff --git a/services/strings/services_strings_fil.xtb b/services/strings/services_strings_fil.xtb
new file mode 100644
index 0000000..16355817f
--- /dev/null
+++ b/services/strings/services_strings_fil.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="fil"></translationbundle>
diff --git a/services/strings/services_strings_fr.xtb b/services/strings/services_strings_fr.xtb
new file mode 100644
index 0000000..dd894bc
--- /dev/null
+++ b/services/strings/services_strings_fr.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="fr"></translationbundle>
diff --git a/services/strings/services_strings_gu.xtb b/services/strings/services_strings_gu.xtb
new file mode 100644
index 0000000..fe3f024c
--- /dev/null
+++ b/services/strings/services_strings_gu.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="gu"></translationbundle>
diff --git a/services/strings/services_strings_hi.xtb b/services/strings/services_strings_hi.xtb
new file mode 100644
index 0000000..5adf9aa
--- /dev/null
+++ b/services/strings/services_strings_hi.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="hi"></translationbundle>
diff --git a/services/strings/services_strings_hr.xtb b/services/strings/services_strings_hr.xtb
new file mode 100644
index 0000000..982aa63
--- /dev/null
+++ b/services/strings/services_strings_hr.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="hr"></translationbundle>
diff --git a/services/strings/services_strings_hu.xtb b/services/strings/services_strings_hu.xtb
new file mode 100644
index 0000000..7fbf3c0
--- /dev/null
+++ b/services/strings/services_strings_hu.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="hu"></translationbundle>
diff --git a/services/strings/services_strings_id.xtb b/services/strings/services_strings_id.xtb
new file mode 100644
index 0000000..2443c4b
--- /dev/null
+++ b/services/strings/services_strings_id.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="id"></translationbundle>
diff --git a/services/strings/services_strings_it.xtb b/services/strings/services_strings_it.xtb
new file mode 100644
index 0000000..d3bbfe4
--- /dev/null
+++ b/services/strings/services_strings_it.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="it"></translationbundle>
diff --git a/services/strings/services_strings_iw.xtb b/services/strings/services_strings_iw.xtb
new file mode 100644
index 0000000..c17190b
--- /dev/null
+++ b/services/strings/services_strings_iw.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="iw"></translationbundle>
diff --git a/services/strings/services_strings_ja.xtb b/services/strings/services_strings_ja.xtb
new file mode 100644
index 0000000..4d8276c
--- /dev/null
+++ b/services/strings/services_strings_ja.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="ja"></translationbundle>
diff --git a/services/strings/services_strings_kn.xtb b/services/strings/services_strings_kn.xtb
new file mode 100644
index 0000000..3b10917
--- /dev/null
+++ b/services/strings/services_strings_kn.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="kn"></translationbundle>
diff --git a/services/strings/services_strings_ko.xtb b/services/strings/services_strings_ko.xtb
new file mode 100644
index 0000000..4de86f28
--- /dev/null
+++ b/services/strings/services_strings_ko.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="ko"></translationbundle>
diff --git a/services/strings/services_strings_lt.xtb b/services/strings/services_strings_lt.xtb
new file mode 100644
index 0000000..753a809
--- /dev/null
+++ b/services/strings/services_strings_lt.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="lt"></translationbundle>
diff --git a/services/strings/services_strings_lv.xtb b/services/strings/services_strings_lv.xtb
new file mode 100644
index 0000000..3de165bb
--- /dev/null
+++ b/services/strings/services_strings_lv.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="lv"></translationbundle>
diff --git a/services/strings/services_strings_ml.xtb b/services/strings/services_strings_ml.xtb
new file mode 100644
index 0000000..c89d799
--- /dev/null
+++ b/services/strings/services_strings_ml.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="ml"></translationbundle>
diff --git a/services/strings/services_strings_mr.xtb b/services/strings/services_strings_mr.xtb
new file mode 100644
index 0000000..8cf1326
--- /dev/null
+++ b/services/strings/services_strings_mr.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="mr"></translationbundle>
diff --git a/services/strings/services_strings_ms.xtb b/services/strings/services_strings_ms.xtb
new file mode 100644
index 0000000..950705f
--- /dev/null
+++ b/services/strings/services_strings_ms.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="ms"></translationbundle>
diff --git a/services/strings/services_strings_nl.xtb b/services/strings/services_strings_nl.xtb
new file mode 100644
index 0000000..f724558f
--- /dev/null
+++ b/services/strings/services_strings_nl.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="nl"></translationbundle>
diff --git a/services/strings/services_strings_no.xtb b/services/strings/services_strings_no.xtb
new file mode 100644
index 0000000..208eaafd
--- /dev/null
+++ b/services/strings/services_strings_no.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="no"></translationbundle>
diff --git a/services/strings/services_strings_pl.xtb b/services/strings/services_strings_pl.xtb
new file mode 100644
index 0000000..27347f6e
--- /dev/null
+++ b/services/strings/services_strings_pl.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="pl"></translationbundle>
diff --git a/services/strings/services_strings_pt-BR.xtb b/services/strings/services_strings_pt-BR.xtb
new file mode 100644
index 0000000..ed9d0cd2
--- /dev/null
+++ b/services/strings/services_strings_pt-BR.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="pt-BR"></translationbundle>
diff --git a/services/strings/services_strings_pt-PT.xtb b/services/strings/services_strings_pt-PT.xtb
new file mode 100644
index 0000000..f6b408a
--- /dev/null
+++ b/services/strings/services_strings_pt-PT.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="pt-PT"></translationbundle>
diff --git a/services/strings/services_strings_ro.xtb b/services/strings/services_strings_ro.xtb
new file mode 100644
index 0000000..cada48eb
--- /dev/null
+++ b/services/strings/services_strings_ro.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="ro"></translationbundle>
diff --git a/services/strings/services_strings_ru.xtb b/services/strings/services_strings_ru.xtb
new file mode 100644
index 0000000..9ac8819
--- /dev/null
+++ b/services/strings/services_strings_ru.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="ru"></translationbundle>
diff --git a/services/strings/services_strings_sk.xtb b/services/strings/services_strings_sk.xtb
new file mode 100644
index 0000000..6498adf
--- /dev/null
+++ b/services/strings/services_strings_sk.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="sk"></translationbundle>
diff --git a/services/strings/services_strings_sl.xtb b/services/strings/services_strings_sl.xtb
new file mode 100644
index 0000000..2350e7d
--- /dev/null
+++ b/services/strings/services_strings_sl.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="sl"></translationbundle>
diff --git a/services/strings/services_strings_sr.xtb b/services/strings/services_strings_sr.xtb
new file mode 100644
index 0000000..82afa24
--- /dev/null
+++ b/services/strings/services_strings_sr.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="sr"></translationbundle>
diff --git a/services/strings/services_strings_sv.xtb b/services/strings/services_strings_sv.xtb
new file mode 100644
index 0000000..9ccd79fe
--- /dev/null
+++ b/services/strings/services_strings_sv.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="sv"></translationbundle>
diff --git a/services/strings/services_strings_sw.xtb b/services/strings/services_strings_sw.xtb
new file mode 100644
index 0000000..e8a33ba
--- /dev/null
+++ b/services/strings/services_strings_sw.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="sw"></translationbundle>
diff --git a/services/strings/services_strings_ta.xtb b/services/strings/services_strings_ta.xtb
new file mode 100644
index 0000000..158c6d6e
--- /dev/null
+++ b/services/strings/services_strings_ta.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="ta"></translationbundle>
diff --git a/services/strings/services_strings_te.xtb b/services/strings/services_strings_te.xtb
new file mode 100644
index 0000000..5f9f108
--- /dev/null
+++ b/services/strings/services_strings_te.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="te"></translationbundle>
diff --git a/services/strings/services_strings_th.xtb b/services/strings/services_strings_th.xtb
new file mode 100644
index 0000000..ec7ae38
--- /dev/null
+++ b/services/strings/services_strings_th.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="th"></translationbundle>
diff --git a/services/strings/services_strings_tr.xtb b/services/strings/services_strings_tr.xtb
new file mode 100644
index 0000000..5cf52f2
--- /dev/null
+++ b/services/strings/services_strings_tr.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="tr"></translationbundle>
diff --git a/services/strings/services_strings_uk.xtb b/services/strings/services_strings_uk.xtb
new file mode 100644
index 0000000..dd923c47
--- /dev/null
+++ b/services/strings/services_strings_uk.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="uk"></translationbundle>
diff --git a/services/strings/services_strings_vi.xtb b/services/strings/services_strings_vi.xtb
new file mode 100644
index 0000000..ea76db62
--- /dev/null
+++ b/services/strings/services_strings_vi.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="vi"></translationbundle>
diff --git a/services/strings/services_strings_zh-CN.xtb b/services/strings/services_strings_zh-CN.xtb
new file mode 100644
index 0000000..e9d4fe0
--- /dev/null
+++ b/services/strings/services_strings_zh-CN.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="zh-CN"></translationbundle>
diff --git a/services/strings/services_strings_zh-TW.xtb b/services/strings/services_strings_zh-TW.xtb
new file mode 100644
index 0000000..d09d6bca
--- /dev/null
+++ b/services/strings/services_strings_zh-TW.xtb
@@ -0,0 +1 @@
+<?xml version="1.0"?><!DOCTYPE translationbundle><translationbundle lang="zh-TW"></translationbundle>
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index bfc1672..765c8264 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -563,11 +563,6 @@
       "chromiumos_preflight"
     ]
   },
-  "chromeos-daisy-rel": {
-    "additional_compile_targets": [
-      "chromiumos_preflight"
-    ]
-  },
   "chromeos-kevin-rel": {
     "additional_compile_targets": [
       "chromiumos_preflight"
diff --git a/testing/buildbot/chromium.dawn.json b/testing/buildbot/chromium.dawn.json
index 051bfd6..b51fc85 100644
--- a/testing/buildbot/chromium.dawn.json
+++ b/testing/buildbot/chromium.dawn.json
@@ -30,6 +30,30 @@
       {
         "args": [
           "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0",
+          "--use-wire"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "dawn_end2end_wire_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "intel-hd-630-ubuntu-stable",
+              "os": "Ubuntu",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "shards": 4
+        },
+        "test": "dawn_end2end_tests"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
           "--use-cmd-decoder=validating"
         ],
         "merge": {
@@ -131,6 +155,30 @@
       {
         "args": [
           "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0",
+          "--use-wire"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "dawn_end2end_wire_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "nvidia-quadro-p400-ubuntu-stable",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "shards": 4
+        },
+        "test": "dawn_end2end_tests"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
           "--use-cmd-decoder=validating"
         ],
         "merge": {
@@ -228,6 +276,30 @@
           "shards": 4
         },
         "test": "dawn_end2end_tests"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0",
+          "--use-wire"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "dawn_end2end_wire_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "intel-hd-630-ubuntu-stable",
+              "os": "Ubuntu",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "shards": 4
+        },
+        "test": "dawn_end2end_tests"
       }
     ]
   },
@@ -254,6 +326,30 @@
           "shards": 4
         },
         "test": "dawn_end2end_tests"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0",
+          "--use-wire"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "dawn_end2end_wire_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "nvidia-quadro-p400-ubuntu-stable",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "shards": 4
+        },
+        "test": "dawn_end2end_tests"
       }
     ]
   },
@@ -287,6 +383,31 @@
       {
         "args": [
           "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0",
+          "--use-wire"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "dawn_end2end_wire_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "1002:6821",
+              "hidpi": "1",
+              "os": "Mac-10.13.6",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "shards": 4
+        },
+        "test": "dawn_end2end_tests"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
           "--use-cmd-decoder=validating"
         ],
         "merge": {
@@ -389,6 +510,30 @@
       {
         "args": [
           "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0",
+          "--use-wire"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "dawn_end2end_wire_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a2e",
+              "os": "Mac-10.13.6",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "shards": 4
+        },
+        "test": "dawn_end2end_tests"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
           "--use-cmd-decoder=validating"
         ],
         "merge": {
@@ -485,6 +630,31 @@
           "shards": 4
         },
         "test": "dawn_end2end_tests"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0",
+          "--use-wire"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "dawn_end2end_wire_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "1002:6821",
+              "hidpi": "1",
+              "os": "Mac-10.13.6",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "shards": 4
+        },
+        "test": "dawn_end2end_tests"
       }
     ]
   },
@@ -511,6 +681,30 @@
           "shards": 4
         },
         "test": "dawn_end2end_tests"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0",
+          "--use-wire"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "dawn_end2end_wire_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a2e",
+              "os": "Mac-10.13.6",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "shards": 4
+        },
+        "test": "dawn_end2end_tests"
       }
     ]
   },
@@ -543,6 +737,30 @@
       {
         "args": [
           "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0",
+          "--use-wire"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "dawn_end2end_wire_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "intel-hd-630-win10-stable",
+              "os": "Windows-10",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "shards": 4
+        },
+        "test": "dawn_end2end_tests"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
           "--use-cmd-decoder=validating"
         ],
         "merge": {
@@ -644,6 +862,30 @@
       {
         "args": [
           "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0",
+          "--use-wire"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "dawn_end2end_wire_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "nvidia-quadro-p400-win10-stable",
+              "os": "Windows-10",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "shards": 4
+        },
+        "test": "dawn_end2end_tests"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
           "--use-cmd-decoder=validating"
         ],
         "merge": {
@@ -741,6 +983,30 @@
           "shards": 4
         },
         "test": "dawn_end2end_tests"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0",
+          "--use-wire"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "dawn_end2end_wire_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "intel-hd-630-win10-stable",
+              "os": "Windows-10",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "shards": 4
+        },
+        "test": "dawn_end2end_tests"
       }
     ]
   },
@@ -767,6 +1033,30 @@
           "shards": 4
         },
         "test": "dawn_end2end_tests"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0",
+          "--use-wire"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "dawn_end2end_wire_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "nvidia-quadro-p400-win10-stable",
+              "os": "Windows-10",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "shards": 4
+        },
+        "test": "dawn_end2end_tests"
       }
     ]
   },
@@ -799,6 +1089,30 @@
       {
         "args": [
           "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0",
+          "--use-wire"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "dawn_end2end_wire_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "intel-hd-630-win10-stable",
+              "os": "Windows-10",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "shards": 4
+        },
+        "test": "dawn_end2end_tests"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
           "--use-cmd-decoder=validating"
         ],
         "merge": {
@@ -898,6 +1212,30 @@
       {
         "args": [
           "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0",
+          "--use-wire"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "dawn_end2end_wire_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "nvidia-quadro-p400-win10-stable",
+              "os": "Windows-10",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "shards": 4
+        },
+        "test": "dawn_end2end_tests"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
           "--use-cmd-decoder=validating"
         ],
         "merge": {
@@ -993,6 +1331,30 @@
           "shards": 4
         },
         "test": "dawn_end2end_tests"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0",
+          "--use-wire"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "dawn_end2end_wire_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "intel-hd-630-win10-stable",
+              "os": "Windows-10",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "shards": 4
+        },
+        "test": "dawn_end2end_tests"
       }
     ]
   },
@@ -1019,6 +1381,30 @@
           "shards": 4
         },
         "test": "dawn_end2end_tests"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0",
+          "--use-wire"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "dawn_end2end_wire_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "nvidia-quadro-p400-win10-stable",
+              "os": "Windows-10",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "shards": 4
+        },
+        "test": "dawn_end2end_tests"
       }
     ]
   }
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json
index 320bac9..ec19ee0 100644
--- a/testing/buildbot/chromium.gpu.fyi.json
+++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -7140,6 +7140,30 @@
           "shards": 4
         },
         "test": "dawn_end2end_tests"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0",
+          "--use-wire"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "dawn_end2end_wire_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "intel-hd-630-ubuntu-stable",
+              "os": "Ubuntu",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "shards": 4
+        },
+        "test": "dawn_end2end_tests"
       }
     ]
   },
@@ -7166,6 +7190,30 @@
           "shards": 4
         },
         "test": "dawn_end2end_tests"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0",
+          "--use-wire"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "dawn_end2end_wire_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "nvidia-quadro-p400-ubuntu-stable",
+              "os": "Ubuntu-14.04",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "shards": 4
+        },
+        "test": "dawn_end2end_tests"
       }
     ]
   },
@@ -7191,6 +7239,29 @@
           "shards": 4
         },
         "test": "dawn_end2end_tests"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0",
+          "--use-wire"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "dawn_end2end_wire_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:0a2e",
+              "os": "Mac-10.12.6"
+            }
+          ],
+          "shards": 4
+        },
+        "test": "dawn_end2end_tests"
       }
     ]
   },
@@ -7218,6 +7289,31 @@
           "shards": 4
         },
         "test": "dawn_end2end_tests"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0",
+          "--use-wire"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "dawn_end2end_wire_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "1002:6821",
+              "hidpi": "1",
+              "os": "Mac-10.13.6",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "shards": 4
+        },
+        "test": "dawn_end2end_tests"
       }
     ]
   },
@@ -7245,6 +7341,31 @@
           "shards": 4
         },
         "test": "dawn_end2end_tests"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0",
+          "--use-wire"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "dawn_end2end_wire_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:0fe9",
+              "hidpi": "1",
+              "os": "Mac-10.13.6",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "shards": 4
+        },
+        "test": "dawn_end2end_tests"
       }
     ]
   },
@@ -7271,6 +7392,30 @@
           "shards": 4
         },
         "test": "dawn_end2end_tests"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0",
+          "--use-wire"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "dawn_end2end_wire_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "intel-hd-630-win10-stable",
+              "os": "Windows-10",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "shards": 4
+        },
+        "test": "dawn_end2end_tests"
       }
     ]
   },
@@ -7297,6 +7442,30 @@
           "shards": 4
         },
         "test": "dawn_end2end_tests"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0",
+          "--use-wire"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "dawn_end2end_wire_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "nvidia-quadro-p400-win10-stable",
+              "os": "Windows-10",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "shards": 4
+        },
+        "test": "dawn_end2end_tests"
       }
     ]
   },
@@ -26093,6 +26262,31 @@
       {
         "args": [
           "--use-gpu-in-tests",
+          "--test-launcher-retry-limit=0",
+          "--use-wire"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "name": "dawn_end2end_wire_tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "10de:2184",
+              "os": "Windows-10",
+              "pool": "Chrome-GPU"
+            }
+          ],
+          "expiration": 21600,
+          "shards": 4
+        },
+        "test": "dawn_end2end_tests"
+      },
+      {
+        "args": [
+          "--use-gpu-in-tests",
           "--use-cmd-decoder=validating"
         ],
         "merge": {
diff --git a/testing/buildbot/chromium.perf.fyi.json b/testing/buildbot/chromium.perf.fyi.json
index dbd2e1f..c4db86f 100644
--- a/testing/buildbot/chromium.perf.fyi.json
+++ b/testing/buildbot/chromium.perf.fyi.json
@@ -47,99 +47,6 @@
       }
     ]
   },
-  "android-pixel2-perf": {
-    "isolated_scripts": [
-      {
-        "args": [
-          "-v",
-          "--browser=exact",
-          "--upload-results",
-          "--browser-executable=../../out/Release/bin/monochrome_64_32_bundle",
-          "--device=android",
-          "--test-shard-map-filename=android-pixel2-perf_map.json"
-        ],
-        "isolate_name": "performance_test_suite",
-        "merge": {
-          "script": "//tools/perf/process_perf_results.py"
-        },
-        "name": "performance_test_suite",
-        "override_compile_targets": [
-          "performance_test_suite"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "device_os": "O",
-              "device_os_flavor": "google",
-              "device_type": "walleye",
-              "os": "Android",
-              "pool": "chrome.tests.perf-fyi"
-            }
-          ],
-          "expiration": 7200,
-          "hard_timeout": 36000,
-          "ignore_task_failure": false,
-          "io_timeout": 1800,
-          "shards": 7
-        },
-        "trigger_script": {
-          "args": [
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "requires_simultaneous_shard_dispatch": true,
-          "script": "//testing/trigger_scripts/perf_device_trigger.py"
-        }
-      }
-    ]
-  },
-  "android-pixel2_webview-perf": {
-    "isolated_scripts": [
-      {
-        "args": [
-          "-v",
-          "--browser=android-webview-google",
-          "--upload-results",
-          "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk",
-          "--test-shard-map-filename=android-pixel2_webview-perf_map.json"
-        ],
-        "isolate_name": "performance_webview_test_suite",
-        "merge": {
-          "script": "//tools/perf/process_perf_results.py"
-        },
-        "name": "performance_webview_test_suite",
-        "override_compile_targets": [
-          "performance_webview_test_suite"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "device_os": "O",
-              "device_os_flavor": "google",
-              "device_type": "walleye",
-              "os": "Android",
-              "pool": "chrome.tests.perf-webview-fyi"
-            }
-          ],
-          "expiration": 7200,
-          "hard_timeout": 36000,
-          "ignore_task_failure": false,
-          "io_timeout": 1800,
-          "shards": 7
-        },
-        "trigger_script": {
-          "args": [
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "requires_simultaneous_shard_dispatch": true,
-          "script": "//testing/trigger_scripts/perf_device_trigger.py"
-        }
-      }
-    ]
-  },
   "linux-perf-fyi": {
     "isolated_scripts": [
       {
diff --git a/testing/buildbot/chromium.perf.json b/testing/buildbot/chromium.perf.json
index 0ea25eb..2a14f13 100644
--- a/testing/buildbot/chromium.perf.json
+++ b/testing/buildbot/chromium.perf.json
@@ -1127,6 +1127,99 @@
       }
     ]
   },
+  "android-pixel2-perf": {
+    "isolated_scripts": [
+      {
+        "args": [
+          "-v",
+          "--browser=exact",
+          "--upload-results",
+          "--browser-executable=../../out/Release/bin/monochrome_64_32_bundle",
+          "--device=android",
+          "--test-shard-map-filename=android-pixel2-perf_map.json"
+        ],
+        "isolate_name": "performance_test_suite",
+        "merge": {
+          "script": "//tools/perf/process_perf_results.py"
+        },
+        "name": "performance_test_suite",
+        "override_compile_targets": [
+          "performance_test_suite"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_os_flavor": "google",
+              "device_type": "walleye",
+              "os": "Android",
+              "pool": "chrome.tests.perf"
+            }
+          ],
+          "expiration": 7200,
+          "hard_timeout": 36000,
+          "ignore_task_failure": false,
+          "io_timeout": 1800,
+          "shards": 35
+        },
+        "trigger_script": {
+          "args": [
+            "--multiple-dimension-script-verbose",
+            "True"
+          ],
+          "requires_simultaneous_shard_dispatch": true,
+          "script": "//testing/trigger_scripts/perf_device_trigger.py"
+        }
+      }
+    ]
+  },
+  "android-pixel2_webview-perf": {
+    "isolated_scripts": [
+      {
+        "args": [
+          "-v",
+          "--browser=android-webview-google",
+          "--upload-results",
+          "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk",
+          "--test-shard-map-filename=android-pixel2_webview-perf_map.json"
+        ],
+        "isolate_name": "performance_webview_test_suite",
+        "merge": {
+          "script": "//tools/perf/process_perf_results.py"
+        },
+        "name": "performance_webview_test_suite",
+        "override_compile_targets": [
+          "performance_webview_test_suite"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "device_os": "O",
+              "device_os_flavor": "google",
+              "device_type": "walleye",
+              "os": "Android",
+              "pool": "chrome.tests.perf-webview"
+            }
+          ],
+          "expiration": 7200,
+          "hard_timeout": 36000,
+          "ignore_task_failure": false,
+          "io_timeout": 1800,
+          "shards": 28
+        },
+        "trigger_script": {
+          "args": [
+            "--multiple-dimension-script-verbose",
+            "True"
+          ],
+          "requires_simultaneous_shard_dispatch": true,
+          "script": "//testing/trigger_scripts/perf_device_trigger.py"
+        }
+      }
+    ]
+  },
   "android_arm64-builder-perf": {
     "additional_compile_targets": [
       "microdump_stackwalk",
diff --git a/testing/buildbot/filters/mojo.fyi.network_chrome_public_test_apk.filter b/testing/buildbot/filters/mojo.fyi.network_chrome_public_test_apk.filter
index 7f1387da..4ed7c723 100644
--- a/testing/buildbot/filters/mojo.fyi.network_chrome_public_test_apk.filter
+++ b/testing/buildbot/filters/mojo.fyi.network_chrome_public_test_apk.filter
@@ -10,20 +10,7 @@
 -org.chromium.chrome.browser.FeaturesAnnotationsTest.testFeaturesSetExistingFlags
 
 # http://crbug.com/917467
+-org.chromium.chrome.browser.webapps.WebApkIntegrationTest.testActivateWebApk
 -org.chromium.chrome.browser.webapps.WebApkIntegrationTest.testLaunchAndNavigateOffOrigin
 -org.chromium.chrome.browser.webapps.WebApkIntegrationTest.testLaunchAndNavigationInNewWindowOffandInOrigin
 -org.chromium.chrome.browser.webapps.WebApkIntegrationTest.testLaunchAndOpenNewWindowInOrigin
-
-# Miscellaneous flaky or failing tests:
-# http://crbug.com/941856
--org.chromium.chrome.browser.webapps.WebApkIntegrationTest.testActivateWebApk
-
-# http://crbug.com/943829
--org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTest.testStartAndAccept
--org.chromium.chrome.browser.autofill.keyboard_accessory.AccessorySheetViewTest.testRemovingTabDeletesItsView
-
-# http://crbug.com/943835
--org.chromium.chrome.browser.widget.OverviewListLayoutTest.testCanSwipeClosed
-
-# http://crbug.com/943847
--org.chromium.chrome.browser.browserservices.TrustedWebActivityTest.launchesTwa
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index f0a5182..409464e 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -3158,6 +3158,18 @@
           'shards': 4,
         },
       },
+      'dawn_end2end_wire_tests': {
+        'desktop_args': [
+          '--use-gpu-in-tests',
+          # Dawn test retries deliberately disabled to prevent flakiness.
+          '--test-launcher-retry-limit=0',
+          '--use-wire',
+        ],
+        'swarming': {
+          'shards': 4,
+        },
+        'test': 'dawn_end2end_tests',
+      },
     },
 
     # GPU gtests that test Dawn and integration with Chromium
@@ -3173,6 +3185,18 @@
           'shards': 4,
         },
       },
+      'dawn_end2end_wire_tests': {
+        'desktop_args': [
+          '--use-gpu-in-tests',
+          # Dawn test retries deliberately disabled to prevent flakiness.
+          '--test-launcher-retry-limit=0',
+          '--use-wire',
+        ],
+        'swarming': {
+          'shards': 4,
+        },
+        'test': 'dawn_end2end_tests',
+      },
       'gl_tests': {
         'desktop_args': [
           '--use-gpu-in-tests',
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index 62a9adf..445c223 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -677,11 +677,6 @@
           'chromiumos_preflight',
         ],
       },
-      'chromeos-daisy-rel': {
-        'additional_compile_targets': [
-          'chromiumos_preflight',
-        ],
-      },
       'chromeos-kevin-rel': {
         'additional_compile_targets': [
           'chromiumos_preflight',
diff --git a/third_party/blink/renderer/core/clipboard/data_transfer.cc b/third_party/blink/renderer/core/clipboard/data_transfer.cc
index c83f49dbc..0769fa7 100644
--- a/third_party/blink/renderer/core/clipboard/data_transfer.cc
+++ b/third_party/blink/renderer/core/clipboard/data_transfer.cc
@@ -119,8 +119,7 @@
 
     FloatRect bounding_box =
         layer->GetLayoutObject()
-            .AbsoluteToLocalQuad(FloatQuad(absolute_bounding_box),
-                                 kUseTransforms)
+            .AbsoluteToLocalQuad(FloatQuad(absolute_bounding_box))
             .BoundingBox();
     PaintLayerPaintingInfo painting_info(
         layer, CullRect(EnclosingIntRect(bounding_box)),
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc b/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc
index 2f0204a5..644274a5 100644
--- a/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc
+++ b/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc
@@ -11,6 +11,8 @@
 #include "third_party/blink/renderer/core/dom/text.h"
 #include "third_party/blink/renderer/core/editing/editing_boundary.h"
 #include "third_party/blink/renderer/core/editing/editing_utilities.h"
+#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
+#include "third_party/blink/renderer/core/layout/layout_view.h"
 
 namespace blink {
 
@@ -166,4 +168,41 @@
   return nullptr;
 }
 
+bool DisplayLockUtilities::IsInLockedSubtreeCrossingFrames(
+    const Node& source_node) {
+  if (!RuntimeEnabledFeatures::DisplayLockingEnabled())
+    return false;
+  const Node* node = &source_node;
+
+  // Special case self-node checking.
+  if (node->GetDocument().LockedDisplayLockCount() && node->IsElementNode()) {
+    auto* context = ToElement(node)->GetDisplayLockContext();
+    if (context && !context->ShouldLayout(DisplayLockContext::kSelf))
+      return true;
+  }
+
+  auto get_frame_owner_node = [](const Node* child) -> const Node* {
+    if (!child || !child->GetDocument().GetFrame() ||
+        !child->GetDocument().GetFrame()->OwnerLayoutObject()) {
+      return nullptr;
+    }
+    return child->GetDocument().GetFrame()->OwnerLayoutObject()->GetNode();
+  };
+
+  // Since we handled the self-check above, we need to do inclusive checks
+  // starting from the parent.
+  node = FlatTreeTraversal::Parent(*node);
+  // If we don't have a flat-tree parent, get the |source_node|'s owner node
+  // instead.
+  if (!node)
+    node = get_frame_owner_node(&source_node);
+
+  while (node) {
+    if (NearestLockedInclusiveAncestor(*node))
+      return true;
+    node = get_frame_owner_node(node);
+  }
+  return false;
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_utilities.h b/third_party/blink/renderer/core/display_lock/display_lock_utilities.h
index c1d0c08..855309e5 100644
--- a/third_party/blink/renderer/core/display_lock/display_lock_utilities.h
+++ b/third_party/blink/renderer/core/display_lock/display_lock_utilities.h
@@ -56,6 +56,10 @@
 
   // Returns the highest exclusive ancestor of |node| that is display locked.
   static Element* HighestLockedExclusiveAncestor(const Node& node);
+
+  // Returns true if the element is in a locked subtree (or is self-locked with
+  // no self-updates). This crosses frames while navigating the ancestor chain.
+  static bool IsInLockedSubtreeCrossingFrames(const Node& node);
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_utilities_test.cc b/third_party/blink/renderer/core/display_lock/display_lock_utilities_test.cc
index 18d7bc6..69e1164 100644
--- a/third_party/blink/renderer/core/display_lock/display_lock_utilities_test.cc
+++ b/third_party/blink/renderer/core/display_lock/display_lock_utilities_test.cc
@@ -3,23 +3,28 @@
 // found in the LICENSE file.
 
 #include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
+
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
 #include "third_party/blink/renderer/core/display_lock/display_lock_context.h"
 #include "third_party/blink/renderer/core/display_lock/display_lock_options.h"
 #include "third_party/blink/renderer/core/dom/shadow_root.h"
+#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
 #include "third_party/blink/renderer/core/testing/page_test_base.h"
 
 namespace blink {
 
-class DisplayLockUtilitiesTest : public PageTestBase {
+class DisplayLockUtilitiesTest : public RenderingTest {
  public:
+  DisplayLockUtilitiesTest()
+      : RenderingTest(MakeGarbageCollected<SingleChildLocalFrameClient>()) {}
+
   void SetUp() override {
-    PageTestBase::SetUp(IntSize());
+    RenderingTest::SetUp();
     RuntimeEnabledFeatures::SetDisplayLockingEnabled(true);
   }
 
   void TearDown() override {
-    PageTestBase::TearDown();
+    RenderingTest::TearDown();
     RuntimeEnabledFeatures::SetDisplayLockingEnabled(false);
   }
 };
@@ -42,6 +47,7 @@
       <div id='innerB'></div>
     </div>
   )HTML");
+
   Element& outer = *GetDocument().getElementById("outer");
   Element& inner_a = *GetDocument().getElementById("innerA");
   Element& inner_b = *GetDocument().getElementById("innerB");
@@ -155,4 +161,99 @@
       0u);
 }
 
+TEST_F(DisplayLockUtilitiesTest, LockedSubtreeCrossingFrames) {
+  GetDocument().SetBaseURLOverride(KURL("http://test.com"));
+  SetBodyInnerHTML(R"HTML(
+    <style>
+      div {
+        contain: style layout;
+      }
+    </style>
+    <div id="grandparent">
+      <iframe id="frame" src="http://test.com"></iframe>
+    </div>
+  )HTML");
+  SetChildFrameHTML(R"HTML(
+    <style>
+      div {
+        contain: style layout;
+      }
+    </style>
+    <div id="parent">
+      <div id="child"></div>
+    </div>
+  )HTML");
+
+  UpdateAllLifecyclePhasesForTest();
+
+  Element* grandparent = GetDocument().getElementById("grandparent");
+  Element* parent = ChildDocument().getElementById("parent");
+  Element* child = ChildDocument().getElementById("child");
+
+  ASSERT_TRUE(grandparent);
+  ASSERT_TRUE(parent);
+  ASSERT_TRUE(child);
+
+  auto* child_frame_state =
+      ToScriptStateForMainWorld(ChildDocument().GetFrame());
+  auto* parent_frame_state =
+      ToScriptStateForMainWorld(GetDocument().GetFrame());
+
+  // Lock parent.
+  {
+    ScriptState::Scope scope(child_frame_state);
+    parent->getDisplayLockForBindings()->acquire(child_frame_state, nullptr);
+  }
+
+  UpdateAllLifecyclePhasesForTest();
+
+  EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 0);
+  EXPECT_EQ(ChildDocument().LockedDisplayLockCount(), 1);
+
+  EXPECT_FALSE(
+      DisplayLockUtilities::IsInLockedSubtreeCrossingFrames(*grandparent));
+  EXPECT_FALSE(DisplayLockUtilities::IsInLockedSubtreeCrossingFrames(*parent));
+  EXPECT_TRUE(DisplayLockUtilities::IsInLockedSubtreeCrossingFrames(*child));
+
+  // Lock grandparent.
+  {
+    ScriptState::Scope scope(parent_frame_state);
+    grandparent->getDisplayLockForBindings()->acquire(parent_frame_state,
+                                                      nullptr);
+  }
+
+  UpdateAllLifecyclePhasesForTest();
+
+  EXPECT_FALSE(
+      DisplayLockUtilities::IsInLockedSubtreeCrossingFrames(*grandparent));
+  EXPECT_TRUE(DisplayLockUtilities::IsInLockedSubtreeCrossingFrames(*parent));
+  EXPECT_TRUE(DisplayLockUtilities::IsInLockedSubtreeCrossingFrames(*child));
+
+  // Unlock parent.
+  {
+    ScriptState::Scope scope(child_frame_state);
+    parent->getDisplayLockForBindings()->commit(child_frame_state);
+  }
+
+  UpdateAllLifecyclePhasesForTest();
+
+  EXPECT_FALSE(
+      DisplayLockUtilities::IsInLockedSubtreeCrossingFrames(*grandparent));
+  EXPECT_TRUE(DisplayLockUtilities::IsInLockedSubtreeCrossingFrames(*parent));
+  EXPECT_TRUE(DisplayLockUtilities::IsInLockedSubtreeCrossingFrames(*child));
+
+  // Unlock grandparent.
+  {
+    ScriptState::Scope scope(parent_frame_state);
+    grandparent->getDisplayLockForBindings()->commit(parent_frame_state);
+  }
+
+  UpdateAllLifecyclePhasesForTest();
+
+  EXPECT_FALSE(
+      DisplayLockUtilities::IsInLockedSubtreeCrossingFrames(*grandparent));
+  EXPECT_FALSE(DisplayLockUtilities::IsInLockedSubtreeCrossingFrames(*parent));
+  EXPECT_FALSE(DisplayLockUtilities::IsInLockedSubtreeCrossingFrames(*child));
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index 1a8ad5c..6a0f2bd 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -1245,9 +1245,10 @@
       !GetLayoutObject()->IsSVGForeignObject()) {
     // Get the bounding rectangle from the SVG model.
     // TODO(pdr): This should include stroke.
-    if (svg_element->IsSVGGraphicsElement())
+    if (svg_element->IsSVGGraphicsElement()) {
       quads.push_back(GetLayoutObject()->LocalToAbsoluteQuad(
           GetLayoutObject()->ObjectBoundingBox()));
+    }
   } else {
     // Get the bounding rectangle from the box model.
     if (GetLayoutBoxModelObject())
@@ -1282,8 +1283,7 @@
   // MapToVisualRectInAncestorSpace applies ancestors' frame's clipping but does
   // not apply (overflow) element clipping.
   GetDocument().View()->GetLayoutView()->MapToVisualRectInAncestorSpace(
-      nullptr, rect, kUseTransforms | kTraverseDocumentBoundaries,
-      kDefaultVisualRectFlags);
+      nullptr, rect, kTraverseDocumentBoundaries, kDefaultVisualRectFlags);
 
   IntRect visible_rect = PixelSnappedIntRect(rect);
   // If the rect is in the coordinates of the main frame, then it should
@@ -1318,16 +1318,17 @@
     // TODO(pdr): ObjectBoundingBox does not include stroke and the spec is not
     // clear (see: https://github.com/w3c/svgwg/issues/339, crbug.com/529734).
     // If stroke is desired, we can update this to use AbsoluteQuads, below.
-    if (svg_element->IsSVGGraphicsElement())
+    if (svg_element->IsSVGGraphicsElement()) {
       quads.push_back(element_layout_object->LocalToAbsoluteQuad(
           element_layout_object->ObjectBoundingBox()));
+    }
     return;
   }
 
   // FIXME: Handle table/inline-table with a caption.
   if (element_layout_object->IsBoxModelObject() ||
       element_layout_object->IsBR())
-    element_layout_object->AbsoluteQuads(quads, kUseTransforms);
+    element_layout_object->AbsoluteQuads(quads);
 }
 
 DOMRectList* Element::getClientRects() {
diff --git a/third_party/blink/renderer/core/dom/events/event_target.cc b/third_party/blink/renderer/core/dom/events/event_target.cc
index d06590d..3fcb76c 100644
--- a/third_party/blink/renderer/core/dom/events/event_target.cc
+++ b/third_party/blink/renderer/core/dom/events/event_target.cc
@@ -446,12 +446,13 @@
       event_type == event_type_names::kTouchend ||
       event_type == event_type_names::kTouchmove ||
       event_type == event_type_names::kTouchstart) {
-    if (options->passive()) {
-      UseCounter::Count(*(ExecutingWindow()->document()),
-                        WebFeature::kPassiveTouchEventListener);
-    } else {
-      UseCounter::Count(*(ExecutingWindow()->document()),
-                        WebFeature::kNonPassiveTouchEventListener);
+    if (const LocalDOMWindow* executing_window = ExecutingWindow()) {
+      if (const Document* document = executing_window->document()) {
+        UseCounter::Count(*document,
+                          options->passive()
+                              ? WebFeature::kPassiveTouchEventListener
+                              : WebFeature::kNonPassiveTouchEventListener);
+      }
     }
   }
 
diff --git a/third_party/blink/renderer/core/editing/editing_utilities.cc b/third_party/blink/renderer/core/editing/editing_utilities.cc
index ea4c0d18..e7d9a428 100644
--- a/third_party/blink/renderer/core/editing/editing_utilities.cc
+++ b/third_party/blink/renderer/core/editing/editing_utilities.cc
@@ -1321,12 +1321,14 @@
     if (!editable_element->GetLayoutObject())
       return PositionWithAffinity();
 
+    // TODO(yosin): This kIgnoreTransforms correct here?
     PhysicalOffset absolute_point =
         target_node->GetLayoutObject()->LocalToAbsolutePoint(
-            PhysicalOffsetToBeNoop(selection_end_point));
-    selection_end_point = editable_element->GetLayoutObject()
-                              ->AbsoluteToLocalPoint(absolute_point)
-                              .ToLayoutPoint();
+            PhysicalOffsetToBeNoop(selection_end_point), kIgnoreTransforms);
+    selection_end_point =
+        editable_element->GetLayoutObject()
+            ->AbsoluteToLocalPoint(absolute_point, kIgnoreTransforms)
+            .ToLayoutPoint();
     target_node = editable_element;
   }
 
diff --git a/third_party/blink/renderer/core/editing/selection_modifier.cc b/third_party/blink/renderer/core/editing/selection_modifier.cc
index efc2bb8..9e1eec8 100644
--- a/third_party/blink/renderer/core/editing/selection_modifier.cc
+++ b/third_party/blink/renderer/core/editing/selection_modifier.cc
@@ -935,7 +935,8 @@
       UNLIKELY(caret_rect.layout_object->HasFlippedBlocksWritingMode())
           ? caret_rect.rect.MaxXMinYCorner()
           : caret_rect.rect.MinXMinYCorner();
-  caret_point = caret_rect.layout_object->LocalToAbsolutePoint(caret_point);
+  caret_point = caret_rect.layout_object->LocalToAbsolutePoint(
+      caret_point, kIgnoreTransforms);
   return caret_rect.layout_object->IsHorizontalWritingMode() ? caret_point.left
                                                              : caret_point.top;
 }
diff --git a/third_party/blink/renderer/core/editing/selection_modifier_line.cc b/third_party/blink/renderer/core/editing/selection_modifier_line.cc
index 3c419c0..85a41e0 100644
--- a/third_party/blink/renderer/core/editing/selection_modifier_line.cc
+++ b/third_party/blink/renderer/core/editing/selection_modifier_line.cc
@@ -113,8 +113,9 @@
       LayoutUnit line_direction_point) {
     DCHECK(!IsNull());
     const LayoutBlockFlow& containing_block = GetBlock();
-    PhysicalOffset absolute_block_point =
-        containing_block.LocalToAbsolutePoint(PhysicalOffset());
+    // TODO(yosin): Is kIgnoreTransforms correct here?
+    PhysicalOffset absolute_block_point = containing_block.LocalToAbsolutePoint(
+        PhysicalOffset(), kIgnoreTransforms);
     if (containing_block.HasOverflowClip()) {
       absolute_block_point -=
           PhysicalOffset(containing_block.ScrolledContentOffset());
diff --git a/third_party/blink/renderer/core/events/mouse_event.cc b/third_party/blink/renderer/core/events/mouse_event.cc
index 7e4805f..4a13e31 100644
--- a/third_party/blink/renderer/core/events/mouse_event.cc
+++ b/third_party/blink/renderer/core/events/mouse_event.cc
@@ -485,7 +485,7 @@
   // Adjust offsetLocation to be relative to the target's padding box.
   if (const LayoutObject* layout_object = FindTargetLayoutObject(target_node)) {
     FloatPoint local_pos = layout_object->AbsoluteToLocalFloatPoint(
-        FloatPoint(AbsoluteLocation()), kUseTransforms);
+        FloatPoint(AbsoluteLocation()));
 
     // Adding this here to address crbug.com/570666. Basically we'd like to
     // find the local coordinates relative to the padding box not the border
diff --git a/third_party/blink/renderer/core/events/web_input_event_conversion.cc b/third_party/blink/renderer/core/events/web_input_event_conversion.cc
index 19b65cf6..1e30316 100644
--- a/third_party/blink/renderer/core/events/web_input_event_conversion.cc
+++ b/third_party/blink/renderer/core/events/web_input_event_conversion.cc
@@ -78,8 +78,7 @@
 FloatPoint ConvertAbsoluteLocationForLayoutObjectFloat(
     const DoublePoint& location,
     const LayoutObject* layout_object) {
-  return layout_object->AbsoluteToLocalFloatPoint(FloatPoint(location),
-                                                  kUseTransforms);
+  return layout_object->AbsoluteToLocalFloatPoint(FloatPoint(location));
 }
 
 // FIXME: Change |LocalFrameView| to const FrameView& after RemoteFrames get
diff --git a/third_party/blink/renderer/core/exported/web_frame_test.cc b/third_party/blink/renderer/core/exported/web_frame_test.cc
index 903c3d82..1d63ddc9 100644
--- a/third_party/blink/renderer/core/exported/web_frame_test.cc
+++ b/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -3130,6 +3130,46 @@
   EXPECT_EQ(2.0f, web_view_helper.GetWebView()->MaximumPageScaleFactor());
 }
 
+// Test that setting the "ignore viewport tag scale limits" override remembers
+// the current defaults and restores them when the override is removed.
+TEST_F(WebFrameTest, RestoreOriginalDefaultScaleLimits) {
+  RegisterMockedHttpURLLoad("simple_div.html");
+
+  FixedLayoutTestWebViewClient client;
+  client.screen_info_.device_scale_factor = 1;
+  int viewport_width = 640;
+  int viewport_height = 480;
+
+  frame_test_helpers::WebViewHelper web_view_helper;
+  web_view_helper.InitializeAndLoad(base_url_ + "simple_div.html", nullptr,
+                                    &client, nullptr, ConfigureAndroid);
+  web_view_helper.Resize(WebSize(viewport_width, viewport_height));
+  web_view_helper.GetWebView()->SetDefaultPageScaleLimits(0.25f, 5);
+
+  const float minimum_scale_factor =
+      web_view_helper.GetWebView()->MinimumPageScaleFactor();
+
+  web_view_helper.GetWebView()->SetInitialPageScaleOverride(2.0f);
+
+  // Removing the override when none is set shouldn't change the initial scale.
+  web_view_helper.GetWebView()->SetIgnoreViewportTagScaleLimits(false);
+  UpdateAllLifecyclePhases(web_view_helper.GetWebView());
+  EXPECT_EQ(2.0f, web_view_helper.GetWebView()->PageScaleFactor());
+
+  // Setting the override when will change the initial scale.
+  web_view_helper.GetWebView()->SetIgnoreViewportTagScaleLimits(true);
+  web_view_helper.GetWebView()->ResetScaleStateImmediately();
+  UpdateAllLifecyclePhases(web_view_helper.GetWebView());
+  EXPECT_EQ(minimum_scale_factor,
+            web_view_helper.GetWebView()->PageScaleFactor());
+
+  // Disable the override, we should now use the minimum scale factor
+  web_view_helper.GetWebView()->SetIgnoreViewportTagScaleLimits(false);
+  web_view_helper.GetWebView()->ResetScaleStateImmediately();
+  UpdateAllLifecyclePhases(web_view_helper.GetWebView());
+  EXPECT_EQ(2.0f, web_view_helper.GetWebView()->PageScaleFactor());
+}
+
 // Android doesn't have scrollbars on the main LocalFrameView
 #if defined(OS_ANDROID)
 TEST_F(WebFrameTest, DISABLED_updateOverlayScrollbarLayers)
diff --git a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
index fbe5dc1..d01f083 100644
--- a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
@@ -650,14 +650,14 @@
   WebPoint point_in_content =
       ParentFrameView()->ConvertFromRootFrame(point_in_root_frame);
   return RoundedIntPoint(GetLayoutEmbeddedContent()->AbsoluteToLocalPoint(
-      PhysicalOffset(point_in_content), kUseTransforms));
+      PhysicalOffset(point_in_content)));
 }
 
 WebPoint WebPluginContainerImpl::LocalToRootFramePoint(
     const WebPoint& point_in_local) {
   IntPoint absolute_point =
       RoundedIntPoint(GetLayoutEmbeddedContent()->LocalToAbsolutePoint(
-          PhysicalOffset(point_in_local), kUseTransforms));
+          PhysicalOffset(point_in_local)));
   return ParentFrameView()->ConvertToRootFrame(absolute_point);
 }
 
@@ -862,8 +862,7 @@
       ParentFrameView()->ConvertFromRootFrame(absolute_location);
 
   FloatPoint local_point =
-      GetLayoutEmbeddedContent()->AbsoluteToLocalFloatPoint(absolute_location,
-                                                            kUseTransforms);
+      GetLayoutEmbeddedContent()->AbsoluteToLocalFloatPoint(absolute_location);
   WebMouseWheelEvent translated_event = event.NativeEvent().FlattenTransform();
   translated_event.SetPositionInWidget(local_point.X(), local_point.Y());
 
@@ -958,8 +957,8 @@
     absolute_location = parent->ConvertFromRootFrame(absolute_location);
 
     FloatPoint local_point =
-        GetLayoutEmbeddedContent()->AbsoluteToLocalFloatPoint(absolute_location,
-                                                              kUseTransforms);
+        GetLayoutEmbeddedContent()->AbsoluteToLocalFloatPoint(
+            absolute_location);
     transformed_event.touches[i].SetPositionInWidget(local_point);
   }
   return transformed_event;
@@ -1022,7 +1021,7 @@
       event.NativeEvent().PositionInRootFrame();
   FloatPoint local_point =
       GetLayoutEmbeddedContent()->AbsoluteToLocalFloatPoint(
-          absolute_root_frame_location, kUseTransforms);
+          absolute_root_frame_location);
   translated_event.FlattenTransform();
   translated_event.SetPositionInWidget(local_point);
 
@@ -1098,12 +1097,12 @@
       PhysicalOffset(), PhysicalSize(root_view->GetFrameView()->Size())));
 
   unclipped_int_local_rect = EnclosingIntRect(box->AbsoluteToLocalRect(
-      unclipped_root_frame_rect, kTraverseDocumentBoundaries | kUseTransforms));
+      unclipped_root_frame_rect, kTraverseDocumentBoundaries));
   // As a performance optimization, map the clipped rect separately if is
   // different than the unclipped rect.
   if (clipped_root_frame_rect != unclipped_root_frame_rect) {
     clipped_local_rect = EnclosingIntRect(box->AbsoluteToLocalRect(
-        clipped_root_frame_rect, kTraverseDocumentBoundaries | kUseTransforms));
+        clipped_root_frame_rect, kTraverseDocumentBoundaries));
   } else {
     clipped_local_rect = unclipped_int_local_rect;
   }
diff --git a/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc b/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc
index 2d6b989..e502736b 100644
--- a/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc
@@ -391,7 +391,7 @@
   LayoutRect absolute_rect =
       owner_object
           ->LocalToAncestorRect(PhysicalRect(rect_to_scroll),
-                                owner_object->View(), kUseTransforms)
+                                owner_object->View())
           .ToLayoutRect();
 
   if (!params.zoom_into_rect ||
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
index 0203d2a..8579333 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -2515,9 +2515,16 @@
 }
 
 void WebViewImpl::SetIgnoreViewportTagScaleLimits(bool ignore) {
+  // This method should be idempotent.
+  if (ignore == pre_override_default_constraints_.has_value())
+    return;
+
   PageScaleConstraints constraints =
       GetPageScaleConstraintsSet().UserAgentConstraints();
   if (ignore) {
+    DCHECK(!pre_override_default_constraints_);
+    pre_override_default_constraints_.emplace(constraints);
+
     constraints.minimum_scale =
         GetPageScaleConstraintsSet().DefaultConstraints().minimum_scale;
     constraints.maximum_scale =
@@ -2525,9 +2532,9 @@
     constraints.initial_scale =
         GetPageScaleConstraintsSet().DefaultConstraints().minimum_scale;
   } else {
-    constraints.minimum_scale = -1;
-    constraints.maximum_scale = -1;
-    constraints.initial_scale = -1;
+    DCHECK(pre_override_default_constraints_);
+    constraints = pre_override_default_constraints_.value();
+    pre_override_default_constraints_.reset();
   }
   GetPage()->SetUserAgentPageScaleConstraints(constraints);
 }
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.h b/third_party/blink/renderer/core/exported/web_view_impl.h
index f7234c6..4d8c735a 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.h
+++ b/third_party/blink/renderer/core/exported/web_view_impl.h
@@ -687,6 +687,10 @@
 
   FloatSize elastic_overscroll_;
 
+  // When overriding the default page scale constraints, store the original so
+  // we can revert to them when the override is removed.
+  base::Optional<PageScaleConstraints> pre_override_default_constraints_;
+
   Persistent<EventListener> popup_mouse_wheel_event_listener_;
 
   // The local root whose document has |popup_mouse_wheel_event_listener_|
diff --git a/third_party/blink/renderer/core/frame/frame_view.cc b/third_party/blink/renderer/core/frame/frame_view.cc
index c4debddc..0ae6f08 100644
--- a/third_party/blink/renderer/core/frame/frame_view.cc
+++ b/third_party/blink/renderer/core/frame/frame_view.cc
@@ -73,7 +73,7 @@
     // geometry.IntersectionRect() is in absolute coordinates of the owning
     // document. Map it down to absolute coordinates in the child document.
     PhysicalRect intersection_rect = owner_layout_object->AncestorToLocalRect(
-        nullptr, geometry.IntersectionRect(), kUseTransforms);
+        nullptr, geometry.IntersectionRect());
     // Map from the box coordinates of the owner to the inner frame.
     intersection_rect.Move(-owner_layout_object->PhysicalContentBoxOffset());
     // Don't let EnclosingIntRect turn an empty rect into a non-empty one.
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
index bf78e7f..15d43f4 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -2990,8 +2990,8 @@
 
 IntRect LocalFrameView::ConvertToLayoutObject(const LayoutObject& layout_object,
                                               const IntRect& frame_rect) const {
-  return PixelSnappedIntRect(layout_object.AbsoluteToLocalRect(
-      PhysicalRect(frame_rect), kUseTransforms));
+  return PixelSnappedIntRect(
+      layout_object.AbsoluteToLocalRect(PhysicalRect(frame_rect)));
 }
 
 IntPoint LocalFrameView::ConvertFromLayoutObject(
@@ -3011,16 +3011,14 @@
 LayoutPoint LocalFrameView::ConvertFromLayoutObject(
     const LayoutObject& layout_object,
     const LayoutPoint& layout_object_point) const {
-  return layout_object
-      .LocalToAbsolutePoint(PhysicalOffset(layout_object_point), kUseTransforms)
+  return layout_object.LocalToAbsolutePoint(PhysicalOffset(layout_object_point))
       .ToLayoutPoint();
 }
 
 PhysicalOffset LocalFrameView::ConvertFromLayoutObject(
     const LayoutObject& layout_object,
     const PhysicalOffset& layout_object_offset) const {
-  return layout_object.LocalToAbsolutePoint(layout_object_offset,
-                                            kUseTransforms);
+  return layout_object.LocalToAbsolutePoint(layout_object_offset);
 }
 
 LayoutPoint LocalFrameView::ConvertToLayoutObject(
@@ -3040,7 +3038,7 @@
 FloatPoint LocalFrameView::ConvertToLayoutObject(
     const LayoutObject& layout_object,
     const FloatPoint& frame_point) const {
-  return layout_object.AbsoluteToLocalFloatPoint(frame_point, kUseTransforms);
+  return layout_object.AbsoluteToLocalFloatPoint(frame_point);
 }
 
 IntPoint LocalFrameView::ConvertSelfToChild(const EmbeddedContentView& child,
@@ -3237,8 +3235,7 @@
     // Add borders and padding
     point.left += layout_object->BorderLeft() + layout_object->PaddingLeft();
     point.top += layout_object->BorderTop() + layout_object->PaddingTop();
-    return FloatPoint(
-        layout_object->LocalToAbsolutePoint(point, kUseTransforms));
+    return FloatPoint(layout_object->LocalToAbsolutePoint(point));
   }
 
   return local_point;
diff --git a/third_party/blink/renderer/core/frame/remote_frame_view.cc b/third_party/blink/renderer/core/frame/remote_frame_view.cc
index b2c2b07..7ab25169 100644
--- a/third_party/blink/renderer/core/frame/remote_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/remote_frame_view.cc
@@ -128,7 +128,7 @@
       remote_frame_->OwnerLayoutObject()->AncestorToLocalRect(
           local_root_view->GetLayoutView(),
           PhysicalRect(PhysicalOffset(), PhysicalSize(viewport_size)),
-          kTraverseDocumentBoundaries | kUseTransforms);
+          kTraverseDocumentBoundaries);
   IntSize converted_viewport_size = EnclosingIntRect(viewport_rect).Size();
 
   IntSize frame_size = Size();
diff --git a/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc b/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc
index 8a791994..a97ced5e 100644
--- a/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc
+++ b/third_party/blink/renderer/core/html/forms/slider_thumb_element.cc
@@ -109,8 +109,8 @@
   if (!input_object || !thumb_box || !track_box)
     return;
 
-  PhysicalOffset point_in_track = track_box->AbsoluteToLocalPoint(
-      PhysicalOffsetToBeNoop(point), kUseTransforms);
+  PhysicalOffset point_in_track =
+      track_box->AbsoluteToLocalPoint(PhysicalOffsetToBeNoop(point));
   bool is_vertical = HasVerticalAppearance(input);
   bool is_left_to_right_direction =
       thumb_box->StyleRef().IsLeftToRightDirection();
diff --git a/third_party/blink/renderer/core/html/forms/spin_button_element.cc b/third_party/blink/renderer/core/html/forms/spin_button_element.cc
index a597dc8..8715d0e 100644
--- a/third_party/blink/renderer/core/html/forms/spin_button_element.cc
+++ b/third_party/blink/renderer/core/html/forms/spin_button_element.cc
@@ -85,7 +85,7 @@
 
   auto& mouse_event = ToMouseEvent(event);
   IntPoint local = RoundedIntPoint(box->AbsoluteToLocalFloatPoint(
-      FloatPoint(mouse_event.AbsoluteLocation()), kUseTransforms));
+      FloatPoint(mouse_event.AbsoluteLocation())));
   if (mouse_event.type() == event_type_names::kMousedown &&
       mouse_event.button() ==
           static_cast<int16_t>(WebPointerProperties::Button::kLeft)) {
diff --git a/third_party/blink/renderer/core/html/html_anchor_element.cc b/third_party/blink/renderer/core/html/html_anchor_element.cc
index 4ab691e4..d57c5bc 100644
--- a/third_party/blink/renderer/core/html/html_anchor_element.cc
+++ b/third_party/blink/renderer/core/html/html_anchor_element.cc
@@ -127,7 +127,7 @@
   // The coordinates sent in the query string are relative to the height and
   // width of the image element, ignoring CSS transform/zoom.
   FloatPoint map_point = layout_object->AbsoluteToLocalFloatPoint(
-      FloatPoint(ToMouseEvent(event)->AbsoluteLocation()), kUseTransforms);
+      FloatPoint(ToMouseEvent(event)->AbsoluteLocation()));
 
   // The origin (0,0) is at the upper left of the content area, inside the
   // padding and border.
diff --git a/third_party/blink/renderer/core/html/html_area_element.cc b/third_party/blink/renderer/core/html/html_area_element.cc
index ca26708..b8a6256 100644
--- a/third_party/blink/renderer/core/html/html_area_element.cc
+++ b/third_party/blink/renderer/core/html/html_area_element.cc
@@ -97,7 +97,8 @@
     return LayoutRect();
 
   // FIXME: This doesn't work correctly with transforms.
-  PhysicalOffset abs_pos = container_object->LocalToAbsolutePoint();
+  PhysicalOffset abs_pos = container_object->LocalToAbsolutePoint(
+      PhysicalOffset(), kIgnoreTransforms);
 
   Path path = GetPath(container_object);
   path.Translate(FloatSize(abs_pos));
diff --git a/third_party/blink/renderer/core/html/html_image_element.cc b/third_party/blink/renderer/core/html/html_image_element.cc
index 5a375a6..b47fb7d 100644
--- a/third_party/blink/renderer/core/html/html_image_element.cc
+++ b/third_party/blink/renderer/core/html/html_image_element.cc
@@ -622,7 +622,8 @@
     return 0;
 
   // FIXME: This doesn't work correctly with transforms.
-  PhysicalOffset abs_pos = r->LocalToAbsolutePoint();
+  PhysicalOffset abs_pos =
+      r->LocalToAbsolutePoint(PhysicalOffset(), kIgnoreTransforms);
   return abs_pos.left.ToInt();
 }
 
@@ -633,7 +634,8 @@
     return 0;
 
   // FIXME: This doesn't work correctly with transforms.
-  PhysicalOffset abs_pos = r->LocalToAbsolutePoint();
+  PhysicalOffset abs_pos =
+      r->LocalToAbsolutePoint(PhysicalOffset(), kIgnoreTransforms);
   return abs_pos.top.ToInt();
 }
 
diff --git a/third_party/blink/renderer/core/input/event_handler.cc b/third_party/blink/renderer/core/input/event_handler.cc
index b490f79a..ebde4d2 100644
--- a/third_party/blink/renderer/core/input/event_handler.cc
+++ b/third_party/blink/renderer/core/input/event_handler.cc
@@ -2294,10 +2294,12 @@
     if (capture_target) {
       LayoutObject* layout_object = capture_target->GetLayoutObject();
 
+      // TODO(eirage): Is kIgnoreTransforms correct here?
       LayoutPoint local_point =
           layout_object ? layout_object
                               ->AbsoluteToLocalPoint(
-                                  PhysicalOffsetToBeNoop(document_point))
+                                  PhysicalOffsetToBeNoop(document_point),
+                                  kIgnoreTransforms)
                               .ToLayoutPoint()
                         : document_point;
 
diff --git a/third_party/blink/renderer/core/inspector/inspector_css_agent.cc b/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
index 46f4618..ac058bc1 100644
--- a/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
@@ -57,6 +57,7 @@
 #include "third_party/blink/renderer/core/css/style_sheet.h"
 #include "third_party/blink/renderer/core/css/style_sheet_contents.h"
 #include "third_party/blink/renderer/core/css/style_sheet_list.h"
+#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/core/dom/dom_node_ids.h"
 #include "third_party/blink/renderer/core/dom/node.h"
@@ -1162,6 +1163,14 @@
   if (!layout_object->IsText()) {
     if (!descendants_depth)
       return;
+
+    // Skip recursing inside a display-locked tree.
+    if (layout_object->GetNode() &&
+        DisplayLockUtilities::NearestLockedInclusiveAncestor(
+            *layout_object->GetNode())) {
+      return;
+    }
+
     if (!layout_object->IsAnonymous())
       --descendants_depth;
     for (LayoutObject* child = layout_object->SlowFirstChild(); child;
@@ -1171,6 +1180,13 @@
     return;
   }
 
+  // Don't gather text on a display-locked tree.
+  if (layout_object->GetNode() &&
+      DisplayLockUtilities::NearestLockedExclusiveAncestor(
+          *layout_object->GetNode())) {
+    return;
+  }
+
   FontCachePurgePreventer preventer;
   LayoutText* layout_text = ToLayoutText(layout_object);
 
diff --git a/third_party/blink/renderer/core/inspector/inspector_highlight.cc b/third_party/blink/renderer/core/inspector/inspector_highlight.cc
index 8f82424..082edae 100644
--- a/third_party/blink/renderer/core/inspector/inspector_highlight.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_highlight.cc
@@ -125,8 +125,10 @@
   FloatPoint TranslatePoint(const FloatPoint& point) override {
     PhysicalOffset layout_object_point = PhysicalOffset::FromFloatPointRound(
         shape_outside_info_.ShapeToLayoutObjectPoint(point));
-    return FloatPoint(view_->FrameToViewport(RoundedIntPoint(
-        layout_object_.LocalToAbsolutePoint(layout_object_point))));
+    // TODO(pfeldman): Is this kIgnoreTransforms correct?
+    return FloatPoint(view_->FrameToViewport(
+        RoundedIntPoint(layout_object_.LocalToAbsolutePoint(
+            layout_object_point, kIgnoreTransforms))));
   }
 
  private:
@@ -320,7 +322,8 @@
   LayoutObject* layout_object = text_node->GetLayoutObject();
   if (!layout_object || !layout_object->IsText())
     return text_info;
-  LayoutRect bounding_box = ToLayoutText(layout_object)->VisualOverflowRect();
+  PhysicalRect bounding_box =
+      ToLayoutText(layout_object)->PhysicalVisualOverflowRect();
   text_info->setString("nodeWidth", bounding_box.Width().ToString());
   text_info->setString("nodeHeight", bounding_box.Height().ToString());
   text_info->setString("tagName", "#text");
@@ -843,8 +846,7 @@
 
   if (layout_object->IsText()) {
     LayoutText* layout_text = ToLayoutText(layout_object);
-    PhysicalRect text_rect =
-        layout_text->FlipForWritingMode(layout_text->VisualOverflowRect());
+    PhysicalRect text_rect = layout_text->PhysicalVisualOverflowRect();
     content_box = text_rect;
     padding_box = text_rect;
     border_box = text_rect;
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc b/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc
index a61f2792..af92219b 100644
--- a/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc
+++ b/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/core/intersection_observer/intersection_geometry.h"
 
+#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
@@ -34,12 +35,12 @@
 }
 
 void MapRectUpToDocument(PhysicalRect& rect, const LayoutObject& descendant) {
-  rect = descendant.LocalToAncestorRect(rect, nullptr, kUseTransforms);
+  rect = descendant.LocalToAncestorRect(rect, nullptr);
 }
 
 void MapRectDownToDocument(PhysicalRect& rect, const Document& document) {
   rect = document.GetLayoutView()->AbsoluteToLocalRect(
-      rect, kUseTransforms | kTraverseDocumentBoundaries);
+      rect, kTraverseDocumentBoundaries);
 }
 
 LayoutUnit ComputeMargin(const Length& length, LayoutUnit reference_length) {
@@ -125,6 +126,11 @@
     return;
   if (root_element && !IsContainingBlockChainDescendant(target, root))
     return;
+  // If the target is inside a locked subtree, it isn't ever visible.
+  if (UNLIKELY(DisplayLockUtilities::IsInLockedSubtreeCrossingFrames(
+          target_element))) {
+    return;
+  }
 
   DCHECK(!target_element.GetDocument().View()->NeedsLayout());
 
@@ -205,8 +211,7 @@
     return PhysicalRect(ToLayoutBoxModelObject(target)->BorderBoundingBox());
   if (target->IsLayoutInline()) {
     return target->AbsoluteToLocalRect(
-        PhysicalRect::EnclosingRect(target->AbsoluteBoundingBoxFloatRect()),
-        kUseTransforms);
+        PhysicalRect::EnclosingRect(target->AbsoluteBoundingBoxFloatRect()));
   }
   return ToLayoutText(target)->PhysicalLinesBoundingBox();
 }
diff --git a/third_party/blink/renderer/core/layout/api/line_layout_item.h b/third_party/blink/renderer/core/layout/api/line_layout_item.h
index a90052f9..ae4d95f 100644
--- a/third_party/blink/renderer/core/layout/api/line_layout_item.h
+++ b/third_party/blink/renderer/core/layout/api/line_layout_item.h
@@ -269,12 +269,6 @@
     return LineLayoutItem(layout_object_->PreviousInPreOrder(stay_within));
   }
 
-  PhysicalOffset LocalToAbsolute(
-      const PhysicalOffset& local_point = PhysicalOffset(),
-      MapCoordinatesFlags flags = 0) const {
-    return layout_object_->LocalToAbsolutePoint(local_point, flags);
-  }
-
   bool HasOverflowClip() const { return layout_object_->HasOverflowClip(); }
 
   // TODO(dgrogan/eae): Can we instead add a TearDown method to the API
diff --git a/third_party/blink/renderer/core/layout/geometry/transform_state.h b/third_party/blink/renderer/core/layout/geometry/transform_state.h
index 3c126df..400f05f 100644
--- a/third_party/blink/renderer/core/layout/geometry/transform_state.h
+++ b/third_party/blink/renderer/core/layout/geometry/transform_state.h
@@ -40,6 +40,10 @@
 
 namespace blink {
 
+// Accumulates transforms/offsets across multiple coordinate spaces.
+// This is mainly used by other layout geometry mapping functions/classes (e.g.
+// LayoutObject::LocalToAncestorPoint() and LayoutGeometryMap). In most cases
+// other code should not use this class directly.
 class CORE_EXPORT TransformState {
   STACK_ALLOCATED();
 
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc
index cc56cfd5..9cbf663 100644
--- a/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -718,7 +718,7 @@
           View()
               ->LocalToAncestorRect(
                   PhysicalRectToBeNoop(absolute_rect_for_parent), parent_view,
-                  kUseTransforms | kTraverseDocumentBoundaries)
+                  kTraverseDocumentBoundaries)
               .ToLayoutRect();
     }
   } else {
@@ -1926,7 +1926,10 @@
 ResourcePriority LayoutBox::ComputeResourcePriority() const {
   PhysicalRect view_bounds = ViewRect();
   PhysicalRect object_bounds = PhysicalContentBoxRect();
-  object_bounds.Move(LocalToAbsolutePoint(PhysicalOffset()));
+  // TODO(japhet): Is this IgnoreTransforms correct? Would it be better to use
+  // the visual rect (which has ancestor clips and transforms applied)? Should
+  // we map to the top-level viewport instead of the current (sub) frame?
+  object_bounds.Move(LocalToAbsolutePoint(PhysicalOffset(), kIgnoreTransforms));
 
   // The object bounds might be empty right now, so intersects will fail since
   // it doesn't deal with empty rects. Use LayoutRect::contains in that case.
diff --git a/third_party/blink/renderer/core/layout/layout_box.h b/third_party/blink/renderer/core/layout/layout_box.h
index 25e57c4..e72f5b6 100644
--- a/third_party/blink/renderer/core/layout/layout_box.h
+++ b/third_party/blink/renderer/core/layout/layout_box.h
@@ -506,8 +506,8 @@
     return LayoutSize(LayoutOverflowRect().MaxX(), LayoutOverflowRect().MaxY());
   }
 
-  LayoutRect VisualOverflowRect() const override;
-  PhysicalRect PhysicalVisualOverflowRect() const {
+  LayoutRect VisualOverflowRect() const;
+  PhysicalRect PhysicalVisualOverflowRect() const final {
     return FlipForWritingMode(VisualOverflowRect());
   }
   LayoutUnit LogicalLeftVisualOverflow() const {
@@ -1442,7 +1442,7 @@
 
   void MapLocalToAncestor(const LayoutBoxModelObject* ancestor,
                           TransformState&,
-                          MapCoordinatesFlags = 0) const override;
+                          MapCoordinatesFlags) const override;
   void MapAncestorToLocal(const LayoutBoxModelObject*,
                           TransformState&,
                           MapCoordinatesFlags) const override;
diff --git a/third_party/blink/renderer/core/layout/layout_box_model_object.cc b/third_party/blink/renderer/core/layout/layout_box_model_object.cc
index 6b50a04..cbe6e6e 100644
--- a/third_party/blink/renderer/core/layout/layout_box_model_object.cc
+++ b/third_party/blink/renderer/core/layout/layout_box_model_object.cc
@@ -835,13 +835,12 @@
   // The sticky position constraint rects should be independent of the current
   // scroll position therefore we should ignore the scroll offset when
   // calculating the quad.
-  MapCoordinatesFlags flags = kIgnoreScrollOffset | kIgnoreStickyOffset;
+  // TODO(crbug.com/966131): Is kIgnoreTransforms correct here?
+  MapCoordinatesFlags flags =
+      kIgnoreTransforms | kIgnoreScrollOffset | kIgnoreStickyOffset;
   skipped_containers_offset =
-      ToFloatSize(location_container
-                      ->LocalToAncestorQuadWithoutTransforms(
-                          FloatQuad(), containing_block, flags)
-                      .BoundingBox()
-                      .Location());
+      FloatSize(location_container->LocalToAncestorPoint(
+          PhysicalOffset(), containing_block, flags));
   LayoutBox& scroll_ancestor =
       ToLayoutBox(Layer()->AncestorOverflowLayer()->GetLayoutObject());
 
@@ -863,12 +862,10 @@
   FloatSize scroll_container_border_offset =
       FloatSize(scroll_ancestor.BorderLeft(), scroll_ancestor.BorderTop());
   if (containing_block != &scroll_ancestor) {
-    FloatQuad local_quad(FloatRect(containing_block->PhysicalPaddingBoxRect()));
+    PhysicalRect local_rect = containing_block->PhysicalPaddingBoxRect();
     scroll_container_relative_padding_box_rect =
-        containing_block
-            ->LocalToAncestorQuadWithoutTransforms(local_quad, &scroll_ancestor,
-                                                   flags)
-            .BoundingBox();
+        FloatRect(containing_block->LocalToAncestorRect(
+            local_rect, &scroll_ancestor, flags));
   }
   // Remove top-left border offset from overflow scroller.
   scroll_container_relative_padding_box_rect.Move(
diff --git a/third_party/blink/renderer/core/layout/layout_box_model_object.h b/third_party/blink/renderer/core/layout/layout_box_model_object.h
index 6aaea9d..23e65eb6 100644
--- a/third_party/blink/renderer/core/layout/layout_box_model_object.h
+++ b/third_party/blink/renderer/core/layout/layout_box_model_object.h
@@ -177,7 +177,7 @@
   // border boxes.
   virtual IntRect BorderBoundingBox() const = 0;
 
-  virtual LayoutRect VisualOverflowRect() const = 0;
+  virtual PhysicalRect PhysicalVisualOverflowRect() const = 0;
 
   bool UsesCompositedScrolling() const;
 
diff --git a/third_party/blink/renderer/core/layout/layout_embedded_content.cc b/third_party/blink/renderer/core/layout/layout_embedded_content.cc
index 39a393b..abd1370 100644
--- a/third_party/blink/renderer/core/layout/layout_embedded_content.cc
+++ b/third_party/blink/renderer/core/layout/layout_embedded_content.cc
@@ -337,14 +337,15 @@
 
 void LayoutEmbeddedContent::UpdateGeometry(
     EmbeddedContentView& embedded_content_view) {
-  // Ignore transform here, as we only care about the sub-pixel accumulation.
-  // TODO(trchen): What about multicol? Need a LayoutBox function to query
-  // sub-pixel accumulation.
+  // TODO(wangxianzhu): We reset subpixel accumulation at some boundaries, so
+  // the following code is incorrect when some ancestors are such boundaries.
+  // What about multicol? Need a LayoutBox function to query sub-pixel
+  // accumulation.
   PhysicalRect replaced_rect = ReplacedContentRect();
   TransformState transform_state(TransformState::kApplyTransformDirection,
                                  FloatPoint(),
                                  FloatQuad(FloatRect(replaced_rect)));
-  MapLocalToAncestor(nullptr, transform_state, kUseTransforms);
+  MapLocalToAncestor(nullptr, transform_state, 0);
   transform_state.Flatten();
   PhysicalOffset absolute_location =
       PhysicalOffset::FromFloatPointRound(transform_state.LastPlanarPoint());
diff --git a/third_party/blink/renderer/core/layout/layout_frame_set.cc b/third_party/blink/renderer/core/layout/layout_frame_set.cc
index 0bc6670..42e2961 100644
--- a/third_party/blink/renderer/core/layout/layout_frame_set.cc
+++ b/third_party/blink/renderer/core/layout/layout_frame_set.cc
@@ -484,8 +484,8 @@
     if (evt.type() == event_type_names::kMousedown &&
         evt.button() ==
             static_cast<int16_t>(WebPointerProperties::Button::kLeft)) {
-      FloatPoint local_pos = AbsoluteToLocalFloatPoint(
-          FloatPoint(evt.AbsoluteLocation()), kUseTransforms);
+      FloatPoint local_pos =
+          AbsoluteToLocalFloatPoint(FloatPoint(evt.AbsoluteLocation()));
       StartResizing(cols_, local_pos.X());
       StartResizing(rows_, local_pos.Y());
       if (cols_.split_being_resized_ != kNoSplit ||
@@ -499,8 +499,8 @@
         (evt.type() == event_type_names::kMouseup &&
          evt.button() ==
              static_cast<int16_t>(WebPointerProperties::Button::kLeft))) {
-      FloatPoint local_pos = AbsoluteToLocalFloatPoint(
-          FloatPoint(evt.AbsoluteLocation()), kUseTransforms);
+      FloatPoint local_pos =
+          AbsoluteToLocalFloatPoint(FloatPoint(evt.AbsoluteLocation()));
       ContinueResizing(cols_, local_pos.X());
       ContinueResizing(rows_, local_pos.Y());
       if (evt.type() == event_type_names::kMouseup &&
diff --git a/third_party/blink/renderer/core/layout/layout_geometry_map.h b/third_party/blink/renderer/core/layout/layout_geometry_map.h
index dfdd726..bddf09f1 100644
--- a/third_party/blink/renderer/core/layout/layout_geometry_map.h
+++ b/third_party/blink/renderer/core/layout/layout_geometry_map.h
@@ -49,7 +49,7 @@
   DISALLOW_NEW();
 
  public:
-  LayoutGeometryMap(MapCoordinatesFlags = kUseTransforms);
+  LayoutGeometryMap(MapCoordinatesFlags = 0);
   ~LayoutGeometryMap();
 
   MapCoordinatesFlags GetMapCoordinatesFlags() const {
diff --git a/third_party/blink/renderer/core/layout/layout_inline.cc b/third_party/blink/renderer/core/layout/layout_inline.cc
index f43364993..17b2b0e 100644
--- a/third_party/blink/renderer/core/layout/layout_inline.cc
+++ b/third_party/blink/renderer/core/layout/layout_inline.cc
@@ -979,7 +979,7 @@
   PhysicalRect rect = UnionRect(rects);
   if (rects.IsEmpty())
     rect.offset = AnchorPhysicalLocation();
-  return LocalToAbsoluteRect(rect, kUseTransforms);
+  return LocalToAbsoluteRect(rect);
 }
 
 LayoutUnit LayoutInline::OffsetLeft(const Element* parent) const {
@@ -1242,11 +1242,16 @@
   return nullptr;
 }
 
-LayoutRect LayoutInline::CulledInlineVisualOverflowBoundingBox() const {
-  LayoutRect result;
-  CollectCulledLineBoxRectsInFlippedBlocksDirection(
-      [&result](const LayoutRect& r) { result.UniteIfNonZero(r); }, this);
+PhysicalRect LayoutInline::CulledInlineVisualOverflowBoundingBox() const {
+  PhysicalRect result;
+  CollectCulledLineBoxRects(
+      [&result](const PhysicalRect& r) { result.UniteIfNonZero(r); });
+  if (!FirstChild())
+    return result;
+
   bool is_horizontal = StyleRef().IsHorizontalWritingMode();
+  const LayoutBlock* block_for_flipping =
+      UNLIKELY(HasFlippedBlocksWritingMode()) ? ContainingBlock() : nullptr;
   for (LayoutObject* curr = FirstChild(); curr; curr = curr->NextSibling()) {
     if (curr->IsFloatingOrOutOfFlowPositioned())
       continue;
@@ -1259,29 +1264,31 @@
             curr_box->LogicalVisualOverflowRectForPropagation();
         if (is_horizontal) {
           logical_rect.MoveBy(curr_box->Location());
-          result.UniteIfNonZero(logical_rect);
+          result.UniteIfNonZero(PhysicalRect(logical_rect));
         } else {
           logical_rect.MoveBy(curr_box->Location());
-          result.UniteIfNonZero(logical_rect.TransposedRect());
+          result.UniteIfNonZero(FlipForWritingMode(
+              logical_rect.TransposedRect(), block_for_flipping));
         }
       }
     } else if (curr->IsLayoutInline()) {
       // If the child doesn't need line boxes either, then we can recur.
       LayoutInline* curr_inline = ToLayoutInline(curr);
-      if (!curr_inline->AlwaysCreateLineBoxes())
+      if (!curr_inline->AlwaysCreateLineBoxes()) {
         result.UniteIfNonZero(
             curr_inline->CulledInlineVisualOverflowBoundingBox());
-      else if (!curr_inline->HasSelfPaintingLayer())
-        result.UniteIfNonZero(curr_inline->VisualOverflowRect());
+      } else if (!curr_inline->HasSelfPaintingLayer()) {
+        result.UniteIfNonZero(curr_inline->PhysicalVisualOverflowRect());
+      }
     } else if (curr->IsText()) {
       LayoutText* curr_text = ToLayoutText(curr);
-      result.UniteIfNonZero(curr_text->VisualOverflowRect());
+      result.UniteIfNonZero(curr_text->PhysicalVisualOverflowRect());
     }
   }
   return result;
 }
 
-LayoutRect LayoutInline::LinesVisualOverflowBoundingBox() const {
+PhysicalRect LayoutInline::LinesVisualOverflowBoundingBox() const {
   if (IsInLayoutNGInlineFormattingContext()) {
     PhysicalRect result;
     NGPaintFragment::InlineFragmentsIncludingCulledFor(
@@ -1293,14 +1300,14 @@
           result->Unite(child_rect);
         },
         &result);
-    return FlipForWritingMode(result);
+    return result;
   }
 
   if (!AlwaysCreateLineBoxes())
     return CulledInlineVisualOverflowBoundingBox();
 
   if (!FirstLineBox() || !LastLineBox())
-    return LayoutRect();
+    return PhysicalRect();
 
   // Return the width of the minimal left side and the maximal right side.
   LayoutUnit logical_left_side = LayoutUnit::Max();
@@ -1326,13 +1333,13 @@
                   logical_height);
   if (!StyleRef().IsHorizontalWritingMode())
     rect = rect.TransposedRect();
-  return rect;
+  return FlipForWritingMode(rect);
 }
 
 PhysicalRect LayoutInline::VisualRectInDocument(VisualRectFlags flags) const {
   PhysicalRect rect;
   if (!Continuation()) {
-    rect = FlipForWritingMode(VisualOverflowRect());
+    rect = PhysicalVisualOverflowRect();
   } else {
     // Should also cover continuations.
     rect = UnionRect(OutlineRects(PhysicalOffset(),
@@ -1354,11 +1361,11 @@
 
   // VisualOverflowRect() is in "physical coordinates with flipped blocks
   // direction", while all "VisualRect"s are in pure physical coordinates.
-  return FlipForWritingMode(VisualOverflowRect());
+  return PhysicalVisualOverflowRect();
 }
 
-LayoutRect LayoutInline::VisualOverflowRect() const {
-  LayoutRect overflow_rect = LinesVisualOverflowBoundingBox();
+PhysicalRect LayoutInline::PhysicalVisualOverflowRect() const {
+  PhysicalRect overflow_rect = LinesVisualOverflowBoundingBox();
   LayoutUnit outline_outset(StyleRef().OutlineOutsetExtent());
   if (outline_outset) {
     Vector<PhysicalRect> rects;
@@ -1378,7 +1385,7 @@
                       OutlineRectsShouldIncludeBlockVisualOverflow());
     }
     if (!rects.IsEmpty()) {
-      LayoutRect outline_rect = FlipForWritingMode(UnionRectEvenIfEmpty(rects));
+      PhysicalRect outline_rect = UnionRectEvenIfEmpty(rects);
       outline_rect.Inflate(outline_outset);
       overflow_rect.Unite(outline_rect);
     }
@@ -1703,12 +1710,16 @@
   region.draggable =
       StyleRef().DraggableRegionMode() == EDraggableRegionMode::kDrag;
   region.bounds = PhysicalLinesBoundingBox();
+  // TODO(crbug.com/966048): We probably want to also cover continuations.
 
   LayoutObject* container = ContainingBlock();
   if (!container)
     container = this;
 
-  region.bounds.offset += container->LocalToAbsolutePoint();
+  // TODO(crbug.com/966048): The kIgnoreTransforms seems incorrect. We probably
+  // want to map visual rect (with clips applied).
+  region.bounds.offset +=
+      container->LocalToAbsolutePoint(PhysicalOffset(), kIgnoreTransforms);
   regions.push_back(region);
 }
 
diff --git a/third_party/blink/renderer/core/layout/layout_inline.h b/third_party/blink/renderer/core/layout/layout_inline.h
index 5d1c691..bae52a7 100644
--- a/third_party/blink/renderer/core/layout/layout_inline.h
+++ b/third_party/blink/renderer/core/layout/layout_inline.h
@@ -147,7 +147,7 @@
   FloatRect LocalBoundingBoxRectForAccessibility() const final;
 
   PhysicalRect PhysicalLinesBoundingBox() const;
-  LayoutRect VisualOverflowRect() const final;
+  PhysicalRect PhysicalVisualOverflowRect() const final;
   PhysicalRect ReferenceBoxForClipPath() const;
 
   InlineFlowBox* CreateAndAppendInlineFlowBox();
@@ -287,13 +287,13 @@
   bool ComputeInitialShouldCreateBoxFragment() const;
   bool ComputeInitialShouldCreateBoxFragment(const ComputedStyle& style) const;
 
-  LayoutRect CulledInlineVisualOverflowBoundingBox() const;
+  PhysicalRect CulledInlineVisualOverflowBoundingBox() const;
   InlineBox* CulledInlineFirstLineBox() const;
   InlineBox* CulledInlineLastLineBox() const;
 
-  // For visualOverflowRect() only, to get bounding box of visual overflow of
-  // line boxes.
-  LayoutRect LinesVisualOverflowBoundingBox() const;
+  // For PhysicalVisualOverflowRect() only, to get bounding box of visual
+  // overflow of line boxes.
+  PhysicalRect LinesVisualOverflowBoundingBox() const;
 
   // PhysicalRectCollector should be like a function:
   // void (const PhysicalRect&).
diff --git a/third_party/blink/renderer/core/layout/layout_media.cc b/third_party/blink/renderer/core/layout/layout_media.cc
index 4bfb10f9..4b970e4 100644
--- a/third_party/blink/renderer/core/layout/layout_media.cc
+++ b/third_party/blink/renderer/core/layout/layout_media.cc
@@ -175,11 +175,11 @@
   // The bottom left corner of the video.
   const FloatPoint bottom_left_point(
       LocalToAbsoluteFloatPoint(FloatPoint(media_rect.X(), media_rect.MaxY()),
-                                kUseTransforms | kTraverseDocumentBoundaries));
+                                kTraverseDocumentBoundaries));
   // The bottom right corner of the video.
   const FloatPoint bottom_right_point(LocalToAbsoluteFloatPoint(
       FloatPoint(media_rect.MaxX(), media_rect.MaxY()),
-      kUseTransforms | kTraverseDocumentBoundaries));
+      kTraverseDocumentBoundaries));
 
   const bool bottom_left_corner_visible = bottom_left_point.X() < visible_width;
   const bool bottom_right_corner_visible =
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc
index c802a67c..689ea16 100644
--- a/third_party/blink/renderer/core/layout/layout_object.cc
+++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -1271,6 +1271,7 @@
 
 FloatRect LayoutObject::AbsoluteBoundingBoxFloatRect(
     MapCoordinatesFlags flags) const {
+  DCHECK(!(flags & kIgnoreTransforms));
   Vector<FloatQuad> quads;
   AbsoluteQuads(quads, flags);
 
@@ -1285,6 +1286,7 @@
 }
 
 IntRect LayoutObject::AbsoluteBoundingBoxRect(MapCoordinatesFlags flags) const {
+  DCHECK(!(flags & kIgnoreTransforms));
   Vector<FloatQuad> quads;
   AbsoluteQuads(quads, flags);
 
@@ -2562,17 +2564,6 @@
   return View()->ViewRect();
 }
 
-FloatPoint LayoutObject::LocalToAbsoluteFloatPoint(
-    const FloatPoint& local_point,
-    MapCoordinatesFlags mode) const {
-  TransformState transform_state(TransformState::kApplyTransformDirection,
-                                 local_point);
-  MapLocalToAncestor(nullptr, transform_state, mode);
-  transform_state.Flatten();
-
-  return transform_state.LastPlanarPoint();
-}
-
 FloatPoint LayoutObject::AncestorToLocalFloatPoint(
     const LayoutBoxModelObject* ancestor,
     const FloatPoint& container_point,
@@ -2627,11 +2618,12 @@
 
   // Text objects just copy their parent's computed style, so we need to ignore
   // them.
+  bool use_transforms = !(mode & kIgnoreTransforms);
   bool preserve3d =
-      mode & kUseTransforms &&
+      use_transforms &&
       ((container->StyleRef().Preserves3D() && !container->IsText()) ||
        (StyleRef().Preserves3D() && !IsText()));
-  if (mode & kUseTransforms && ShouldUseTransformFromContainer(container)) {
+  if (use_transforms && ShouldUseTransformFromContainer(container)) {
     TransformationMatrix t;
     GetTransformFromContainer(container, container_offset, t);
     transform_state.ApplyTransform(t, preserve3d
@@ -2685,10 +2677,10 @@
     container->MapAncestorToLocal(ancestor, transform_state, mode);
 
   PhysicalOffset container_offset = OffsetFromContainer(container);
-  bool preserve3d =
-      mode & kUseTransforms &&
-      (container->StyleRef().Preserves3D() || StyleRef().Preserves3D());
-  if (mode & kUseTransforms && ShouldUseTransformFromContainer(container)) {
+  bool use_transforms = !(mode & kIgnoreTransforms);
+  bool preserve3d = use_transforms && (container->StyleRef().Preserves3D() ||
+                                       StyleRef().Preserves3D());
+  if (use_transforms && ShouldUseTransformFromContainer(container)) {
     TransformationMatrix t;
     GetTransformFromContainer(container, container_offset, t);
     transform_state.ApplyTransform(t, preserve3d
@@ -2763,28 +2755,24 @@
   }
 }
 
+FloatPoint LayoutObject::LocalToAncestorFloatPoint(
+    const FloatPoint& local_point,
+    const LayoutBoxModelObject* ancestor,
+    MapCoordinatesFlags mode) const {
+  TransformState transform_state(TransformState::kApplyTransformDirection,
+                                 local_point);
+  MapLocalToAncestor(ancestor, transform_state, mode);
+  transform_state.Flatten();
+
+  return transform_state.LastPlanarPoint();
+}
+
 FloatQuad LayoutObject::LocalToAncestorQuad(
     const FloatQuad& local_quad,
     const LayoutBoxModelObject* ancestor,
     MapCoordinatesFlags mode) const {
-  return LocalToAncestorQuadInternal(local_quad, ancestor,
-                                     mode | kUseTransforms);
-}
-
-FloatQuad LayoutObject::LocalToAncestorQuadWithoutTransforms(
-    const FloatQuad& local_quad,
-    const LayoutBoxModelObject* ancestor,
-    MapCoordinatesFlags mode) const {
-  DCHECK(!(mode & kUseTransforms));
-  return LocalToAncestorQuadInternal(local_quad, ancestor, mode);
-}
-
-FloatQuad LayoutObject::LocalToAncestorQuadInternal(
-    const FloatQuad& local_quad,
-    const LayoutBoxModelObject* ancestor,
-    MapCoordinatesFlags mode) const {
   // Track the point at the center of the quad's bounding box. As
-  // mapLocalToAncestor() calls offsetFromContainer(), it will use that point
+  // MapLocalToAncestor() calls OffsetFromContainer(), it will use that point
   // as the reference point to decide which column's transform to apply in
   // multiple-column blocks.
   TransformState transform_state(TransformState::kApplyTransformDirection,
@@ -2795,18 +2783,6 @@
   return transform_state.LastPlanarQuad();
 }
 
-PhysicalOffset LayoutObject::LocalToAncestorPoint(
-    const PhysicalOffset& local_point,
-    const LayoutBoxModelObject* ancestor,
-    MapCoordinatesFlags mode) const {
-  TransformState transform_state(TransformState::kApplyTransformDirection,
-                                 FloatPoint(local_point));
-  MapLocalToAncestor(ancestor, transform_state, mode | kUseTransforms);
-  transform_state.Flatten();
-
-  return PhysicalOffset::FromFloatPointRound(transform_state.LastPlanarPoint());
-}
-
 void LayoutObject::LocalToAncestorRects(
     Vector<PhysicalRect>& rects,
     const LayoutBoxModelObject* ancestor,
@@ -2831,8 +2807,9 @@
 TransformationMatrix LayoutObject::LocalToAncestorTransform(
     const LayoutBoxModelObject* ancestor,
     MapCoordinatesFlags mode) const {
+  DCHECK(!(mode & kIgnoreTransforms));
   TransformState transform_state(TransformState::kApplyTransformDirection);
-  MapLocalToAncestor(ancestor, transform_state, mode | kUseTransforms);
+  MapLocalToAncestor(ancestor, transform_state, mode);
   return transform_state.AccumulatedTransform();
 }
 
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h
index 19eac2d..74334a2 100644
--- a/third_party/blink/renderer/core/layout/layout_object.h
+++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -1527,46 +1527,90 @@
     return bitfields_.CanContainFixedPositionObjects();
   }
 
-  // Convert the given local physical point to absolute coordinates.
-  // FIXME: Temporary. If UseTransforms is true, take transforms into account.
-  // Eventually LocalToAbsolute() will be transform-aware by default.
-  PhysicalOffset LocalToAbsolutePoint(
-      const PhysicalOffset& local_point = PhysicalOffset(),
-      MapCoordinatesFlags mode = 0) const {
-    return PhysicalOffset::FromFloatPointRound(
-        LocalToAbsoluteFloatPoint(FloatPoint(local_point), mode));
-  }
-  FloatPoint LocalToAbsoluteFloatPoint(const FloatPoint&,
-                                       MapCoordinatesFlags mode = 0) const;
-
-  // If the LayoutBoxModelObject ancestor is non-null, the input point is in the
+  // Convert a rect/quad/point in ancestor coordinates to local physical
+  // coordinates, taking transforms into account unless kIgnoreTransforms (not
+  // allowed in the quad versions) is specified.
+  // PhysicalRect parameter/return value is preferred to Float because they
+  // force physical coordinates, unless we do need quads or float precision.
+  // If the LayoutBoxModelObject ancestor is non-null, the input is in the
   // space of the ancestor.
   // Otherwise:
-  //   If TraverseDocumentBoundaries is specified, the input point is in the
-  //   space of the local root frame.
-  //   Otherwise, the input point is in the space of the containing frame.
+  //   If kTraverseDocumentBoundaries is specified, the input is in the space of
+  //   the local root frame.
+  //   Otherwise, the input is in the space of the containing frame.
+  PhysicalRect AncestorToLocalRect(const LayoutBoxModelObject* ancestor,
+                                   const PhysicalRect& rect,
+                                   MapCoordinatesFlags mode = 0) const {
+    return PhysicalRect::EnclosingRect(
+        AncestorToLocalQuad(ancestor, FloatRect(rect), mode).BoundingBox());
+  }
+  FloatQuad AncestorToLocalQuad(const LayoutBoxModelObject*,
+                                const FloatQuad&,
+                                MapCoordinatesFlags mode = 0) const;
   PhysicalOffset AncestorToLocalPoint(const LayoutBoxModelObject* ancestor,
                                       const PhysicalOffset& p,
                                       MapCoordinatesFlags mode = 0) const {
     return PhysicalOffset::FromFloatPointRound(
         AncestorToLocalFloatPoint(ancestor, FloatPoint(p), mode));
   }
-  PhysicalOffset AbsoluteToLocalPoint(const PhysicalOffset& p,
-                                      MapCoordinatesFlags mode = 0) const {
-    return AncestorToLocalPoint(nullptr, p, mode);
-  }
   FloatPoint AncestorToLocalFloatPoint(const LayoutBoxModelObject* ancestor,
                                        const FloatPoint& p,
                                        MapCoordinatesFlags = 0) const;
-  FloatPoint AbsoluteToLocalFloatPoint(const FloatPoint& p,
-                                       MapCoordinatesFlags mode = 0) const {
-    return AncestorToLocalFloatPoint(nullptr, p, mode);
+
+  // Convert a rect/quad/point in local physical coordinates into ancestor
+  // coordinates, taking transforms into account unless kIgnoreTransforms is
+  // specified.
+  // PhysicalRect parameter/return value is preferred to Float because they
+  // force physical coordinates, unless we do need quads or float precision.
+  // If the LayoutBoxModelObject ancestor is non-null, the result will be in the
+  // space of the ancestor.
+  // Otherwise:
+  //   If TraverseDocumentBoundaries is specified, the result will be in the
+  //   space of the local root frame.
+  //   Otherwise, the result will be in the space of the containing frame.
+  PhysicalRect LocalToAncestorRect(const PhysicalRect& rect,
+                                   const LayoutBoxModelObject* ancestor,
+                                   MapCoordinatesFlags mode = 0) const {
+    return PhysicalRect::EnclosingRect(
+        LocalToAncestorQuad(FloatRect(rect), ancestor, mode).BoundingBox());
+  }
+  FloatQuad LocalRectToAncestorQuad(const PhysicalRect& rect,
+                                    const LayoutBoxModelObject* ancestor,
+                                    MapCoordinatesFlags mode = 0) const {
+    return LocalToAncestorQuad(FloatRect(rect), ancestor, mode);
+  }
+  FloatQuad LocalToAncestorQuad(const FloatQuad&,
+                                const LayoutBoxModelObject* ancestor,
+                                MapCoordinatesFlags = 0) const;
+  PhysicalOffset LocalToAncestorPoint(const PhysicalOffset& p,
+                                      const LayoutBoxModelObject* ancestor,
+                                      MapCoordinatesFlags mode = 0) const {
+    return PhysicalOffset::FromFloatPointRound(
+        LocalToAncestorFloatPoint(FloatPoint(p), ancestor, mode));
+  }
+  FloatPoint LocalToAncestorFloatPoint(const FloatPoint&,
+                                       const LayoutBoxModelObject* ancestor,
+                                       MapCoordinatesFlags = 0) const;
+  void LocalToAncestorRects(Vector<PhysicalRect>&,
+                            const LayoutBoxModelObject* ancestor,
+                            const PhysicalOffset& pre_offset,
+                            const PhysicalOffset& post_offset) const;
+
+  // Return the transformation matrix to map points from local to the coordinate
+  // system of a container, taking transforms into account (kIgnoreTransforms is
+  // not allowed).
+  // Passing null for |ancestor| behaves the same as LocalToAncestorRect.
+  TransformationMatrix LocalToAncestorTransform(
+      const LayoutBoxModelObject* ancestor,
+      MapCoordinatesFlags = 0) const;
+  TransformationMatrix LocalToAbsoluteTransform(
+      MapCoordinatesFlags mode = 0) const {
+    return LocalToAncestorTransform(nullptr, mode);
   }
 
-  // Convert a rect/quad in local physical coordinates to absolute coordinates,
-  // taking transforms into account. PhysicalRect parameter/return value is
-  // preferred to FloatQuad because they force physical coordinates, unless we
-  // do need quads or float precision.
+  // Shorthands of the above LocalToAncestor* and AncestorToLocal* functions,
+  // with nullptr as the ancestor. See the above functions for the meaning of
+  // "absolute" coordinates.
   PhysicalRect LocalToAbsoluteRect(const PhysicalRect& rect,
                                    MapCoordinatesFlags mode = 0) const {
     return LocalToAncestorRect(rect, nullptr, mode);
@@ -1579,25 +1623,14 @@
                                 MapCoordinatesFlags mode = 0) const {
     return LocalToAncestorQuad(quad, nullptr, mode);
   }
-
-  // Convert a quad/rect in ancestor coordinates to local coordinates.
-  // PhysicalRect parameter/return value is preferred to FloatQuad because they
-  // force physical coordinates, unless we do need quads or float precision.
-  // If the LayoutBoxModelObject ancestor is non-null, the input quad is in the
-  // space of the ancestor.
-  // Otherwise:
-  //   If TraverseDocumentBoundaries is specified, the input quad is in the
-  //   space of the local root frame.
-  //   Otherwise, the input quad is in the space of the containing frame.
-  PhysicalRect AncestorToLocalRect(const LayoutBoxModelObject* ancestor,
-                                   const PhysicalRect& rect,
-                                   MapCoordinatesFlags mode = 0) const {
-    return PhysicalRect::EnclosingRect(
-        AncestorToLocalQuad(ancestor, FloatRect(rect), mode).BoundingBox());
+  PhysicalOffset LocalToAbsolutePoint(const PhysicalOffset& p,
+                                      MapCoordinatesFlags mode = 0) const {
+    return LocalToAncestorPoint(p, nullptr, mode);
   }
-  FloatQuad AncestorToLocalQuad(const LayoutBoxModelObject*,
-                                const FloatQuad&,
-                                MapCoordinatesFlags mode = 0) const;
+  FloatPoint LocalToAbsoluteFloatPoint(const FloatPoint& p,
+                                       MapCoordinatesFlags mode = 0) const {
+    return LocalToAncestorFloatPoint(p, nullptr, mode);
+  }
   PhysicalRect AbsoluteToLocalRect(const PhysicalRect& rect,
                                    MapCoordinatesFlags mode = 0) const {
     return AncestorToLocalRect(nullptr, rect, mode);
@@ -1606,55 +1639,13 @@
                                 MapCoordinatesFlags mode = 0) const {
     return AncestorToLocalQuad(nullptr, quad, mode);
   }
-
-  // Convert a quad/rect in local physical coordinates into the coordinate
-  // system of container, taking transforms into account.
-  // PhysicalRect parameter/return value is preferred to FloatQuad because they
-  // force physical coordinates, unless we do need quads or float precision.
-  // If the LayoutBoxModelObject ancestor is non-null, the result will be in the
-  // space of the ancestor.
-  // Otherwise:
-  //   If TraverseDocumentBoundaries is specified, the result will be in the
-  //   space of the local root frame.
-  //   Otherwise, the result will be in the space of the containing frame.
-  PhysicalRect LocalToAncestorRect(const PhysicalRect& rect,
-                                   const LayoutBoxModelObject* ancestor,
-                                   MapCoordinatesFlags mode = 0) const {
-    return PhysicalRect::EnclosingRect(
-        LocalRectToAncestorQuad(rect, ancestor, mode).BoundingBox());
+  PhysicalOffset AbsoluteToLocalPoint(const PhysicalOffset& p,
+                                      MapCoordinatesFlags mode = 0) const {
+    return AncestorToLocalPoint(nullptr, p, mode);
   }
-  FloatQuad LocalRectToAncestorQuad(const PhysicalRect& rect,
-                                    const LayoutBoxModelObject* ancestor,
-                                    MapCoordinatesFlags mode = 0) const {
-    return LocalToAncestorQuad(FloatRect(rect), ancestor, mode);
-  }
-  FloatQuad LocalToAncestorQuad(const FloatQuad&,
-                                const LayoutBoxModelObject* ancestor,
-                                MapCoordinatesFlags = 0) const;
-  PhysicalOffset LocalToAncestorPoint(const PhysicalOffset&,
-                                      const LayoutBoxModelObject* ancestor,
-                                      MapCoordinatesFlags = 0) const;
-  void LocalToAncestorRects(Vector<PhysicalRect>&,
-                            const LayoutBoxModelObject* ancestor,
-                            const PhysicalOffset& pre_offset,
-                            const PhysicalOffset& post_offset) const;
-
-  // Convert a local quad into the coordinate system of container, not
-  // include transforms. See LocalToAncestorQuad() for details.
-  FloatQuad LocalToAncestorQuadWithoutTransforms(
-      const FloatQuad&,
-      const LayoutBoxModelObject* ancestor,
-      MapCoordinatesFlags = 0) const;
-
-  // Return the transformation matrix to map points from local to the coordinate
-  // system of a container, taking transforms into account.
-  // Passing null for |ancestor| behaves the same as localToAncestorQuad.
-  TransformationMatrix LocalToAncestorTransform(
-      const LayoutBoxModelObject* ancestor,
-      MapCoordinatesFlags = 0) const;
-  TransformationMatrix LocalToAbsoluteTransform(
-      MapCoordinatesFlags mode = 0) const {
-    return LocalToAncestorTransform(nullptr, mode);
+  FloatPoint AbsoluteToLocalFloatPoint(const FloatPoint& p,
+                                       MapCoordinatesFlags mode = 0) const {
+    return AncestorToLocalFloatPoint(nullptr, p, mode);
   }
 
   // Return the offset from the container() layoutObject (excluding transforms
@@ -1958,7 +1949,7 @@
   // absoluteToLocal methods instead.
   virtual void MapLocalToAncestor(const LayoutBoxModelObject* ancestor,
                                   TransformState&,
-                                  MapCoordinatesFlags = 0) const;
+                                  MapCoordinatesFlags) const;
   // If the LayoutBoxModelObject ancestor is non-null, the input quad is in the
   // space of the ancestor.
   // Otherwise:
@@ -1967,7 +1958,7 @@
   //   Otherwise, the input quad is in the space of the containing frame.
   virtual void MapAncestorToLocal(const LayoutBoxModelObject*,
                                   TransformState&,
-                                  MapCoordinatesFlags = 0) const;
+                                  MapCoordinatesFlags) const;
 
   // Pushes state onto LayoutGeometryMap about how to map coordinates from this
   // layoutObject to its container, or ancestorToStopAt (whichever is
diff --git a/third_party/blink/renderer/core/layout/layout_text.cc b/third_party/blink/renderer/core/layout/layout_text.cc
index 1356d385..00166c6 100644
--- a/third_party/blink/renderer/core/layout/layout_text.cc
+++ b/third_party/blink/renderer/core/layout/layout_text.cc
@@ -1971,13 +1971,13 @@
   return result;
 }
 
-LayoutRect LayoutText::VisualOverflowRect() const {
-  if (base::Optional<PhysicalRect> physical_rect =
+PhysicalRect LayoutText::PhysicalVisualOverflowRect() const {
+  if (base::Optional<PhysicalRect> rect =
           NGPaintFragment::LocalVisualRectFor(*this))
-    return FlipForWritingMode(*physical_rect);
+    return *rect;
 
   if (!FirstTextBox())
-    return LayoutRect();
+    return PhysicalRect();
 
   // Return the width of the minimal left side and the maximal right side.
   LayoutUnit logical_left_side = LayoutUnit::Max();
@@ -2017,16 +2017,11 @@
                   logical_height);
   if (!StyleRef().IsHorizontalWritingMode())
     rect = rect.TransposedRect();
-  return rect;
+  return FlipForWritingMode(rect);
 }
 
 PhysicalRect LayoutText::LocalVisualRectIgnoringVisibility() const {
-  PhysicalRect rect;
-  if (const auto& r = NGPaintFragment::LocalVisualRectFor(*this))
-    rect = *r;
-  else
-    rect = FlipForWritingMode(VisualOverflowRect());
-  return UnionRect(rect, LocalSelectionVisualRect());
+  return UnionRect(PhysicalVisualOverflowRect(), LocalSelectionVisualRect());
 }
 
 PhysicalRect LayoutText::LocalSelectionVisualRect() const {
diff --git a/third_party/blink/renderer/core/layout/layout_text.h b/third_party/blink/renderer/core/layout/layout_text.h
index 7d2ce62..94dc1ea 100644
--- a/third_party/blink/renderer/core/layout/layout_text.h
+++ b/third_party/blink/renderer/core/layout/layout_text.h
@@ -184,7 +184,7 @@
 
   // Returns the bounding box of visual overflow rects of all line boxes,
   // in containing block's physical coordinates with flipped blocks direction.
-  LayoutRect VisualOverflowRect() const;
+  PhysicalRect PhysicalVisualOverflowRect() const;
 
   PhysicalOffset FirstLineBoxTopLeft() const;
 
diff --git a/third_party/blink/renderer/core/layout/layout_view.cc b/third_party/blink/renderer/core/layout/layout_view.cc
index ce8e4e9..c25edce 100644
--- a/third_party/blink/renderer/core/layout/layout_view.cc
+++ b/third_party/blink/renderer/core/layout/layout_view.cc
@@ -353,7 +353,7 @@
 void LayoutView::MapLocalToAncestor(const LayoutBoxModelObject* ancestor,
                                     TransformState& transform_state,
                                     MapCoordinatesFlags mode) const {
-  if (!ancestor && mode & kUseTransforms &&
+  if (!ancestor && !(mode & kIgnoreTransforms) &&
       ShouldUseTransformFromContainer(nullptr)) {
     TransformationMatrix t;
     GetTransformFromContainer(nullptr, PhysicalOffset(), t);
diff --git a/third_party/blink/renderer/core/layout/layout_view.h b/third_party/blink/renderer/core/layout/layout_view.h
index e245ca4..fd7f8d5 100644
--- a/third_party/blink/renderer/core/layout/layout_view.h
+++ b/third_party/blink/renderer/core/layout/layout_view.h
@@ -275,7 +275,7 @@
  private:
   void MapLocalToAncestor(const LayoutBoxModelObject* ancestor,
                           TransformState&,
-                          MapCoordinatesFlags = 0) const override;
+                          MapCoordinatesFlags) const override;
 
   const LayoutObject* PushMappingToContainer(
       const LayoutBoxModelObject* ancestor_to_stop_at,
diff --git a/third_party/blink/renderer/core/layout/layout_vtt_cue.cc b/third_party/blink/renderer/core/layout/layout_vtt_cue.cc
index 02a8743..a2fe1cd 100644
--- a/third_party/blink/renderer/core/layout/layout_vtt_cue.cc
+++ b/third_party/blink/renderer/core/layout/layout_vtt_cue.cc
@@ -122,8 +122,7 @@
   PhysicalRect cue_content_box = box.PhysicalContentBoxRect();
   // We pass UseTransforms here primarily because we use a transform for
   // non-snap-to-lines positioning (see VTTCue.cpp.)
-  return EnclosingIntRect(
-      box.LocalToAncestorRect(cue_content_box, &ancestor, kUseTransforms));
+  return EnclosingIntRect(box.LocalToAncestorRect(cue_content_box, &ancestor));
 }
 
 // Similar to above except uses the full bounding box instead of just the
@@ -134,8 +133,7 @@
   PhysicalRect cue_content_box = box.PhysicalPaddingBoxRect();
   // We pass UseTransforms here primarily because we use a transform for
   // non-snap-to-lines positioning (see VTTCue.cpp.)
-  return EnclosingIntRect(
-      box.LocalToAncestorRect(cue_content_box, &ancestor, kUseTransforms));
+  return EnclosingIntRect(box.LocalToAncestorRect(cue_content_box, &ancestor));
 }
 
 IntRect CueBoundingBox(const LayoutBox& cue_box) {
diff --git a/third_party/blink/renderer/core/layout/map_coordinates_flags.h b/third_party/blink/renderer/core/layout/map_coordinates_flags.h
index fc9ff1a5..0c634d3 100644
--- a/third_party/blink/renderer/core/layout/map_coordinates_flags.h
+++ b/third_party/blink/renderer/core/layout/map_coordinates_flags.h
@@ -9,7 +9,9 @@
 
 enum MapCoordinatesMode {
   kIsFixed = 1 << 0,
-  kUseTransforms = 1 << 1,
+
+  // Only needed in some special cases to intentionally ignore transforms.
+  kIgnoreTransforms = 1 << 2,
 
   kTraverseDocumentBoundaries = 1 << 3,
 
diff --git a/third_party/blink/renderer/core/layout/map_coordinates_test.cc b/third_party/blink/renderer/core/layout/map_coordinates_test.cc
index 122b819..b5b5bde 100644
--- a/third_party/blink/renderer/core/layout/map_coordinates_test.cc
+++ b/third_party/blink/renderer/core/layout/map_coordinates_test.cc
@@ -620,9 +620,9 @@
   ASSERT_TRUE(view->IsLayoutView());
 
   PhysicalOffset mapped_point =
-      MapLocalToAncestor(target, view, PhysicalOffset(), kUseTransforms);
+      MapLocalToAncestor(target, view, PhysicalOffset());
   EXPECT_EQ(AdjustForFrameScroll(PhysicalOffset(0, 200)), mapped_point);
-  mapped_point = MapAncestorToLocal(target, view, mapped_point, kUseTransforms);
+  mapped_point = MapAncestorToLocal(target, view, mapped_point);
   EXPECT_EQ(PhysicalOffset(), mapped_point);
 
   mapped_point = MapLocalToAncestor(target, container, PhysicalOffset());
@@ -630,11 +630,9 @@
   mapped_point = MapAncestorToLocal(target, container, PhysicalOffset(0, 0));
   EXPECT_EQ(PhysicalOffset(), mapped_point);
 
-  mapped_point =
-      MapLocalToAncestor(container, view, PhysicalOffset(), kUseTransforms);
+  mapped_point = MapLocalToAncestor(container, view, PhysicalOffset());
   EXPECT_EQ(AdjustForFrameScroll(PhysicalOffset(0, 200)), mapped_point);
-  mapped_point =
-      MapAncestorToLocal(container, view, mapped_point, kUseTransforms);
+  mapped_point = MapAncestorToLocal(container, view, mapped_point);
   EXPECT_EQ(PhysicalOffset(), mapped_point);
 }
 
@@ -730,9 +728,9 @@
 
   Element* target = ChildDocument().getElementById("target");
   ASSERT_TRUE(target);
-  PhysicalOffset mapped_point = MapAncestorToLocal(
-      target->GetLayoutObject(), nullptr, PhysicalOffset(200, 200),
-      kTraverseDocumentBoundaries | kUseTransforms);
+  PhysicalOffset mapped_point =
+      MapAncestorToLocal(target->GetLayoutObject(), nullptr,
+                         PhysicalOffset(200, 200), kTraverseDocumentBoundaries);
 
   // Derivation:
   // (200, 200) -> (-50, -50)  (Adjust for transform origin of scale, which is
@@ -766,9 +764,9 @@
 
   Element* target = ChildDocument().getElementById("target");
   ASSERT_TRUE(target);
-  PhysicalOffset mapped_point = MapAncestorToLocal(
-      target->GetLayoutObject(), nullptr, PhysicalOffset(0, 0),
-      kUseTransforms | kTraverseDocumentBoundaries);
+  PhysicalOffset mapped_point =
+      MapAncestorToLocal(target->GetLayoutObject(), nullptr,
+                         PhysicalOffset(0, 0), kTraverseDocumentBoundaries);
 
   EXPECT_EQ(PhysicalOffset(0, 0), mapped_point);
 }
@@ -1356,13 +1354,11 @@
 
   FloatQuad initial_quad(FloatPoint(0, 0), FloatPoint(200, 0),
                          FloatPoint(200, 200), FloatPoint(0, 200));
-  FloatQuad mapped_quad =
-      MapLocalToAncestor(target, container, initial_quad, kUseTransforms);
+  FloatQuad mapped_quad = MapLocalToAncestor(target, container, initial_quad);
   EXPECT_FLOAT_QUAD_EQ(FloatQuad(FloatPoint(200, 0), FloatPoint(200, 200),
                                  FloatPoint(0, 200), FloatPoint(0, 0)),
                        mapped_quad);
-  mapped_quad =
-      MapAncestorToLocal(target, container, mapped_quad, kUseTransforms);
+  mapped_quad = MapAncestorToLocal(target, container, mapped_quad);
   EXPECT_FLOAT_QUAD_EQ(initial_quad, mapped_quad);
 
   // Walk each ancestor in the chain separately, to verify each step on the way.
@@ -1371,38 +1367,34 @@
   LayoutBox* outer_transform =
       ToLayoutBox(GetLayoutObjectByElementId("outerTransform"));
 
-  mapped_quad =
-      MapLocalToAncestor(target, inner_transform, initial_quad, kUseTransforms);
+  mapped_quad = MapLocalToAncestor(target, inner_transform, initial_quad);
   EXPECT_FLOAT_QUAD_EQ(FloatQuad(FloatPoint(0, 0), FloatPoint(200, 0),
                                  FloatPoint(200, 200), FloatPoint(0, 200)),
                        mapped_quad);
-  mapped_quad =
-      MapAncestorToLocal(target, inner_transform, mapped_quad, kUseTransforms);
+  mapped_quad = MapAncestorToLocal(target, inner_transform, mapped_quad);
   EXPECT_FLOAT_QUAD_EQ(initial_quad, mapped_quad);
 
   initial_quad = FloatQuad(FloatPoint(0, 0), FloatPoint(200, 0),
                            FloatPoint(200, 200), FloatPoint(0, 200));
-  mapped_quad = MapLocalToAncestor(inner_transform, outer_transform,
-                                   initial_quad, kUseTransforms);
+  mapped_quad =
+      MapLocalToAncestor(inner_transform, outer_transform, initial_quad);
   // Clockwise rotation by 45 degrees.
   EXPECT_FLOAT_QUAD_EQ(
       FloatQuad(FloatPoint(100, -41.42), FloatPoint(241.42, 100),
                 FloatPoint(100, 241.42), FloatPoint(-41.42, 100)),
       mapped_quad);
-  mapped_quad = MapAncestorToLocal(inner_transform, outer_transform,
-                                   mapped_quad, kUseTransforms);
+  mapped_quad =
+      MapAncestorToLocal(inner_transform, outer_transform, mapped_quad);
   EXPECT_FLOAT_QUAD_EQ(initial_quad, mapped_quad);
 
   initial_quad = FloatQuad(FloatPoint(100, -41.42), FloatPoint(241.42, 100),
                            FloatPoint(100, 241.42), FloatPoint(-41.42, 100));
-  mapped_quad = MapLocalToAncestor(outer_transform, container, initial_quad,
-                                   kUseTransforms);
+  mapped_quad = MapLocalToAncestor(outer_transform, container, initial_quad);
   // Another clockwise rotation by 45 degrees. So now 90 degrees in total.
   EXPECT_FLOAT_QUAD_EQ(FloatQuad(FloatPoint(200, 0), FloatPoint(200, 200),
                                  FloatPoint(0, 200), FloatPoint(0, 0)),
                        mapped_quad);
-  mapped_quad = MapAncestorToLocal(outer_transform, container, mapped_quad,
-                                   kUseTransforms);
+  mapped_quad = MapAncestorToLocal(outer_transform, container, mapped_quad);
   EXPECT_FLOAT_QUAD_EQ(initial_quad, mapped_quad);
 }
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
index 85617dc..41949702e 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
@@ -251,9 +251,7 @@
     // may have gained or removed scrollbars, changing its size). In these
     // cases "simplified" layout will return a null layout-result, indicating
     // we need to perform a full layout.
-    layout_result =
-        NGSimplifiedLayoutAlgorithm(params, *box_->GetCachedLayoutResult())
-            .Layout();
+    layout_result = RunSimplifiedLayout(params);
 
 #if DCHECK_IS_ON()
     if (layout_result) {
@@ -1045,6 +1043,12 @@
   return layout_result;
 }
 
+scoped_refptr<const NGLayoutResult> NGBlockNode::RunSimplifiedLayout(
+    const NGLayoutAlgorithmParams& params) const {
+  return NGSimplifiedLayoutAlgorithm(params, *box_->GetCachedLayoutResult())
+      .Layout();
+}
+
 void NGBlockNode::CopyBaselinesFromLegacyLayout(
     const NGConstraintSpace& constraint_space,
     NGBoxFragmentBuilder* builder) {
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.h b/third_party/blink/renderer/core/layout/ng/ng_block_node.h
index e099162..329908a 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_node.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.h
@@ -24,6 +24,7 @@
 class NGPhysicalFragment;
 struct MinMaxSize;
 struct NGBoxStrut;
+struct NGLayoutAlgorithmParams;
 struct LogicalOffset;
 
 // Represents a node to be laid out.
@@ -108,10 +109,6 @@
       FontBaseline,
       bool use_first_line_style);
 
-  // Runs layout on the underlying LayoutObject and creates a fragment for the
-  // resulting geometry.
-  scoped_refptr<const NGLayoutResult> RunLegacyLayout(const NGConstraintSpace&);
-
   // Called if this is an out-of-flow block which needs to be
   // positioned with legacy layout.
   void UseLegacyOutOfFlowPositioning() const;
@@ -131,6 +128,13 @@
  private:
   void PrepareForLayout();
 
+  // Runs layout on the underlying LayoutObject and creates a fragment for the
+  // resulting geometry.
+  scoped_refptr<const NGLayoutResult> RunLegacyLayout(const NGConstraintSpace&);
+
+  scoped_refptr<const NGLayoutResult> RunSimplifiedLayout(
+      const NGLayoutAlgorithmParams&) const;
+
   // If this node is a LayoutNGMixin, the caller must pass the layout object for
   // this node cast to a LayoutBlockFlow as the first argument.
   void FinishLayout(LayoutBlockFlow*,
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_block.h b/third_party/blink/renderer/core/layout/svg/layout_svg_block.h
index f3ff9d1..739c40a 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_block.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_block.h
@@ -41,10 +41,10 @@
   // These mapping functions map coordinates in HTML spaces.
   void MapLocalToAncestor(const LayoutBoxModelObject* ancestor,
                           TransformState&,
-                          MapCoordinatesFlags = 0) const final;
+                          MapCoordinatesFlags) const final;
   void MapAncestorToLocal(const LayoutBoxModelObject* ancestor,
                           TransformState&,
-                          MapCoordinatesFlags = 0) const final;
+                          MapCoordinatesFlags) const final;
   const LayoutObject* PushMappingToContainer(
       const LayoutBoxModelObject* ancestor_to_stop_at,
       LayoutGeometryMap&) const final;
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object_test.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object_test.cc
index f41cfb9d..f680a1ba 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object_test.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object_test.cc
@@ -39,21 +39,15 @@
   EXPECT_TRUE(div.MapToVisualRectInAncestorSpace(&GetLayoutView(), div_rect));
   EXPECT_EQ(PhysicalRect(150, 150, 100, 50), div_rect);
 
-  // MapLocalToAncestor
-  TransformState transform_state(TransformState::kApplyTransformDirection,
-                                 FloatPoint());
-  div.MapLocalToAncestor(&GetLayoutView(), transform_state,
-                         kTraverseDocumentBoundaries);
-  transform_state.Flatten();
-  EXPECT_EQ(FloatPoint(150, 150), transform_state.LastPlanarPoint());
+  // LocalToAncestorPoint
+  EXPECT_EQ(PhysicalOffset(150, 150),
+            div.LocalToAncestorPoint(PhysicalOffset(), &GetLayoutView(),
+                                     kTraverseDocumentBoundaries));
 
   // MapAncestorToLocal
-  TransformState transform_state1(
-      TransformState::kUnapplyInverseTransformDirection, FloatPoint());
-  div.MapAncestorToLocal(&GetLayoutView(), transform_state1,
-                         kTraverseDocumentBoundaries);
-  transform_state1.Flatten();
-  EXPECT_EQ(FloatPoint(-150, -150), transform_state1.LastPlanarPoint());
+  EXPECT_EQ(PhysicalOffset(-150, -150),
+            div.AncestorToLocalPoint(&GetLayoutView(), PhysicalOffset(),
+                                     kTraverseDocumentBoundaries));
 
   // PushMappingToContainer
   LayoutGeometryMap rgm(kTraverseDocumentBoundaries);
@@ -115,21 +109,15 @@
   EXPECT_TRUE(div.MapToVisualRectInAncestorSpace(&GetLayoutView(), div_rect));
   EXPECT_EQ(PhysicalRect(200, 200, 100, 50), div_rect);
 
-  // MapLocalToAncestor
-  TransformState transform_state(TransformState::kApplyTransformDirection,
-                                 FloatPoint());
-  div.MapLocalToAncestor(&GetLayoutView(), transform_state,
-                         kTraverseDocumentBoundaries);
-  transform_state.Flatten();
-  EXPECT_EQ(FloatPoint(200, 200), transform_state.LastPlanarPoint());
+  // LocalToAncestorPoint
+  EXPECT_EQ(PhysicalOffset(200, 200),
+            div.LocalToAncestorPoint(PhysicalOffset(), &GetLayoutView(),
+                                     kTraverseDocumentBoundaries));
 
-  // MapAncestorToLocal
-  TransformState transform_state1(
-      TransformState::kUnapplyInverseTransformDirection, FloatPoint());
-  div.MapAncestorToLocal(&GetLayoutView(), transform_state1,
-                         kTraverseDocumentBoundaries);
-  transform_state1.Flatten();
-  EXPECT_EQ(FloatPoint(-200, -200), transform_state1.LastPlanarPoint());
+  // AncestorToLocalPoint
+  EXPECT_EQ(PhysicalOffset(-200, -200),
+            div.AncestorToLocalPoint(&GetLayoutView(), PhysicalOffset(),
+                                     kTraverseDocumentBoundaries));
 
   // PushMappingToContainer
   LayoutGeometryMap rgm(kTraverseDocumentBoundaries);
@@ -188,23 +176,18 @@
       &GetLayoutView(), div_rect));
   EXPECT_EQ(PhysicalRect(286, 286, 339, 170), div_rect);
 
-  // MapLocalToAncestor
-  TransformState transform_state(TransformState::kApplyTransformDirection,
-                                 FloatPoint());
-  div.GetLayoutObject()->MapLocalToAncestor(&GetLayoutView(), transform_state,
-                                            kTraverseDocumentBoundaries);
-  transform_state.Flatten();
-  EXPECT_EQ(FloatPoint(286.875, 286.875),
-            FloatPoint(transform_state.LastPlanarPoint()));
+  // LocalToAncestorPoint
+  EXPECT_EQ(
+      PhysicalOffset(LayoutUnit(286.875), LayoutUnit(286.875)),
+      div.GetLayoutObject()->LocalToAncestorPoint(
+          PhysicalOffset(), &GetLayoutView(), kTraverseDocumentBoundaries));
 
-  // MapAncestorToLocal
-  TransformState transform_state1(
-      TransformState::kUnapplyInverseTransformDirection,
-      transform_state.LastPlanarPoint());
-  div.GetLayoutObject()->MapAncestorToLocal(&GetLayoutView(), transform_state1,
-                                            kTraverseDocumentBoundaries);
-  transform_state1.Flatten();
-  EXPECT_EQ(FloatPoint(), transform_state1.LastPlanarPoint());
+  // AncestorToLocalPoint
+  EXPECT_EQ(PhysicalOffset(),
+            div.GetLayoutObject()->AncestorToLocalPoint(
+                &GetLayoutView(),
+                PhysicalOffset(LayoutUnit(286.875), LayoutUnit(286.875)),
+                kTraverseDocumentBoundaries));
 
   EXPECT_EQ(svg, HitTest(20, 20));
   EXPECT_EQ(foreign, HitTest(280, 280));
@@ -236,21 +219,16 @@
   const auto& foreign = *GetDocument().getElementById("foreign");
   const auto& div = *GetDocument().getElementById("div");
 
-  // MapLocalToAncestor
-  TransformState transform_state(TransformState::kApplyTransformDirection,
-                                 FloatPoint());
-  div.GetLayoutObject()->MapLocalToAncestor(&GetLayoutView(), transform_state,
-                                            kTraverseDocumentBoundaries);
-  transform_state.Flatten();
-  EXPECT_EQ(FloatPoint(128, 128), transform_state.LastPlanarPoint());
+  // LocalToAncestorPoint
+  EXPECT_EQ(
+      PhysicalOffset(128, 128),
+      div.GetLayoutObject()->LocalToAncestorPoint(
+          PhysicalOffset(), &GetLayoutView(), kTraverseDocumentBoundaries));
 
-  // MapAncestorToLocal
-  TransformState transform_state1(
-      TransformState::kUnapplyInverseTransformDirection, FloatPoint(128, 128));
-  div.GetLayoutObject()->MapAncestorToLocal(&GetLayoutView(), transform_state1,
-                                            kTraverseDocumentBoundaries);
-  transform_state1.Flatten();
-  EXPECT_EQ(FloatPoint(), transform_state1.LastPlanarPoint());
+  // AncestorToLocalPoint
+  EXPECT_EQ(PhysicalOffset(), div.GetLayoutObject()->AncestorToLocalPoint(
+                                  &GetLayoutView(), PhysicalOffset(128, 128),
+                                  kTraverseDocumentBoundaries));
 
   EXPECT_EQ(svg, HitTest(20, 20));
   EXPECT_EQ(foreign, HitTest(120, 110));
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_inline.h b/third_party/blink/renderer/core/layout/svg/layout_svg_inline.h
index 84724dec..6322b62 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_inline.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_inline.h
@@ -51,7 +51,7 @@
       VisualRectFlags = kDefaultVisualRectFlags) const final;
   void MapLocalToAncestor(const LayoutBoxModelObject* ancestor,
                           TransformState&,
-                          MapCoordinatesFlags = 0) const final;
+                          MapCoordinatesFlags) const final;
   const LayoutObject* PushMappingToContainer(
       const LayoutBoxModelObject* ancestor_to_stop_at,
       LayoutGeometryMap&) const final;
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.h b/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.h
index e729aab..ab5ee1f0 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_model_object.h
@@ -60,10 +60,10 @@
 
   void MapLocalToAncestor(const LayoutBoxModelObject* ancestor,
                           TransformState&,
-                          MapCoordinatesFlags = 0) const final;
+                          MapCoordinatesFlags) const final;
   void MapAncestorToLocal(const LayoutBoxModelObject* ancestor,
                           TransformState&,
-                          MapCoordinatesFlags = 0) const final;
+                          MapCoordinatesFlags) const final;
   const LayoutObject* PushMappingToContainer(
       const LayoutBoxModelObject* ancestor_to_stop_at,
       LayoutGeometryMap&) const final;
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_root.h b/third_party/blink/renderer/core/layout/svg/layout_svg_root.h
index 1342b15..ff3fc5a5 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_root.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_root.h
@@ -144,7 +144,7 @@
 
   void MapLocalToAncestor(const LayoutBoxModelObject* ancestor,
                           TransformState&,
-                          MapCoordinatesFlags = 0) const override;
+                          MapCoordinatesFlags) const override;
   const LayoutObject* PushMappingToContainer(
       const LayoutBoxModelObject* ancestor_to_stop_at,
       LayoutGeometryMap&) const override;
diff --git a/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc b/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc
index 865459c..22bb64f 100644
--- a/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc
+++ b/third_party/blink/renderer/core/layout/svg/svg_layout_support.cc
@@ -174,8 +174,7 @@
   const LayoutSVGRoot& svg_root =
       ComputeTransformToSVGRoot(object, local_to_svg_root);
 
-  MapCoordinatesFlags mode = flags | kUseTransforms;
-  svg_root.MapAncestorToLocal(ancestor, transform_state, mode);
+  svg_root.MapAncestorToLocal(ancestor, transform_state, flags);
 
   transform_state.ApplyTransform(local_to_svg_root);
 }
diff --git a/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc b/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc
index aea4ab0..89d6f8ef 100644
--- a/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc
+++ b/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc
@@ -259,8 +259,8 @@
   // to its container's border box. And the |area| below represents the
   // snap_area rect in respect to the snap_container.
   PhysicalRect area_rect = snap_area.PhysicalBorderBoxRect();
-  area_rect = snap_area.LocalToAncestorRect(
-      area_rect, &snap_container, kUseTransforms | kTraverseDocumentBoundaries);
+  area_rect = snap_area.LocalToAncestorRect(area_rect, &snap_container,
+                                            kTraverseDocumentBoundaries);
   ScrollableArea* scrollable_area = ScrollableAreaForSnapping(snap_container);
   if (scrollable_area) {
     if (snap_container.IsLayoutView()) {
diff --git a/third_party/blink/renderer/core/paint/background_image_geometry.cc b/third_party/blink/renderer/core/paint/background_image_geometry.cc
index b89c2117..a2d5a2d 100644
--- a/third_party/blink/renderer/core/paint/background_image_geometry.cc
+++ b/third_party/blink/renderer/core/paint/background_image_geometry.cc
@@ -389,6 +389,8 @@
 LayoutRect FixedAttachmentPositioningArea(const LayoutBoxModelObject& obj,
                                           const LayoutBoxModelObject* container,
                                           const GlobalPaintFlags flags) {
+  // TODO(crbug.com/966142): We should consider ancestor with transform as the
+  // fixed background container, instead of always the viewport.
   LocalFrameView* frame_view = obj.View()->GetFrameView();
   if (!frame_view)
     return LayoutRect();
@@ -419,7 +421,8 @@
 
   if (container) {
     rect.MoveBy(
-        -container->LocalToAbsolutePoint(PhysicalOffset()).ToLayoutPoint());
+        -container->LocalToAbsolutePoint(PhysicalOffset(), kIgnoreTransforms)
+             .ToLayoutPoint());
   }
 
   // By now we have converted the viewport rect to the border box space of
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
index 9ee763c1..989d333 100644
--- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
+++ b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
@@ -691,8 +691,7 @@
   }
 
   FloatRect bounds_in_ancestor_space(GetLayoutObject().LocalToAncestorRect(
-      composited_bounds_, &clip_inheritance_ancestor_->GetLayoutObject(),
-      kUseTransforms));
+      composited_bounds_, &clip_inheritance_ancestor_->GetLayoutObject()));
   owning_layer_is_masked =
       AncestorRoundedCornersWillClip(bounds_in_ancestor_space);
 }
@@ -1525,15 +1524,11 @@
     } else {
       // The controls are in the same 2D space as the compositing container, so
       // we can map them into the space of the container.
-      // TODO(wangxianzhu): Use LocalToAncestorPoint() when it supports
-      // ignoring transforms.
-      TransformState transform_state(TransformState::kApplyTransformDirection,
-                                     FloatPoint());
-      owning_layer_.GetLayoutObject().MapLocalToAncestor(
-          &compositing_stacking_context->GetLayoutObject(), transform_state);
-      transform_state.Flatten();
-      host_layer_position = PhysicalOffset::FromFloatPointRound(
-          transform_state.LastPlanarPoint());
+      host_layer_position =
+          owning_layer_.GetLayoutObject().LocalToAncestorPoint(
+              PhysicalOffset(),
+              &compositing_stacking_context->GetLayoutObject(),
+              kIgnoreTransforms);
       if (PaintLayerScrollableArea* scrollable_area =
               compositing_stacking_context->GetScrollableArea()) {
         host_layer_position += PhysicalOffset::FromFloatPointRound(
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc b/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc
index 2e55036..d170400 100644
--- a/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc
+++ b/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc
@@ -27,8 +27,7 @@
 CompositingInputsUpdater::CompositingInputsUpdater(
     PaintLayer* root_layer,
     PaintLayer* compositing_inputs_root)
-    : geometry_map_(kUseTransforms),
-      root_layer_(root_layer),
+    : root_layer_(root_layer),
       compositing_inputs_root_(compositing_inputs_root) {}
 
 CompositingInputsUpdater::~CompositingInputsUpdater() = default;
diff --git a/third_party/blink/renderer/core/paint/link_highlight_impl.cc b/third_party/blink/renderer/core/paint/link_highlight_impl.cc
index 3cb0c4c..4fa0f546 100644
--- a/third_party/blink/renderer/core/paint/link_highlight_impl.cc
+++ b/third_party/blink/renderer/core/paint/link_highlight_impl.cc
@@ -236,7 +236,7 @@
     absolute_quad.SetP4(FloatPoint(RoundedIntPoint(absolute_quad.P4())));
     FloatQuad transformed_quad =
         paint_invalidation_container.AbsoluteToLocalQuad(
-            absolute_quad, kUseTransforms | kTraverseDocumentBoundaries);
+            absolute_quad, kTraverseDocumentBoundaries);
     PhysicalOffset offset_to_backing;
 
     PaintLayer::MapPointInPaintInvalidationContainerToBacking(
diff --git a/third_party/blink/renderer/core/paint/paint_layer.cc b/third_party/blink/renderer/core/paint/paint_layer.cc
index 59cc2ff..8e2333e2 100644
--- a/third_party/blink/renderer/core/paint/paint_layer.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -712,9 +712,9 @@
     needs_descendant_dependent_flags_update_ = false;
 
     if (IsSelfPaintingLayer() && needs_visual_overflow_recalc_) {
-      LayoutRect old_visual_rect = GetLayoutObject().VisualOverflowRect();
+      auto old_visual_rect = GetLayoutObject().PhysicalVisualOverflowRect();
       GetLayoutObject().RecalcVisualOverflow();
-      if (old_visual_rect != GetLayoutObject().VisualOverflowRect()) {
+      if (old_visual_rect != GetLayoutObject().PhysicalVisualOverflowRect()) {
         SetNeedsCompositingInputsUpdateInternal();
         MarkAncestorChainForFlagsUpdate(DoesNotNeedDescendantDependentUpdate);
       }
@@ -965,19 +965,15 @@
 
 PhysicalOffset PaintLayer::ComputeOffsetFromAncestor(
     const PaintLayer& ancestor_layer) const {
-  // TODO(wangxianzhu): Use LocalToAncestorPoint() when it supports ignoring
-  // transforms.
-  TransformState transform_state(TransformState::kApplyTransformDirection,
-                                 FloatPoint());
   const LayoutBoxModelObject& ancestor_object =
       ancestor_layer.GetLayoutObject();
-  GetLayoutObject().MapLocalToAncestor(&ancestor_object, transform_state, 0);
+  PhysicalOffset result = GetLayoutObject().LocalToAncestorPoint(
+      PhysicalOffset(), &ancestor_object, kIgnoreTransforms);
   if (ancestor_object.UsesCompositedScrolling()) {
-    transform_state.Move(
-        PhysicalOffset(ToLayoutBox(ancestor_object).ScrolledContentOffset()));
+    result +=
+        PhysicalOffset(ToLayoutBox(ancestor_object).ScrolledContentOffset());
   }
-  transform_state.Flatten();
-  return PhysicalOffset::FromFloatPointRound(transform_state.LastPlanarPoint());
+  return result;
 }
 
 PaintLayer* PaintLayer::CompositingContainer() const {
@@ -1533,7 +1529,8 @@
       (!ancestor_layer || ancestor_layer == layout_object.View()->Layer())) {
     // If the fixed layer's container is the root, just add in the offset of the
     // view. We can obtain this by calling localToAbsolute() on the LayoutView.
-    location += layout_object.LocalToAbsolutePoint();
+    location +=
+        layout_object.LocalToAbsolutePoint(PhysicalOffset(), kIgnoreTransforms);
     return ancestor_layer;
   }
 
@@ -2569,19 +2566,11 @@
 }
 
 PhysicalRect PaintLayer::LocalBoundingBox() const {
-  PhysicalRect rect;
-  if (GetLayoutObject().IsBox()) {
-    rect = ToLayoutBox(GetLayoutObject()).PhysicalVisualOverflowRect();
-  } else {
-    LayoutRect layout_rect = GetLayoutObject().VisualOverflowRect();
-    rect = GetLayoutObject().FlipForWritingMode(layout_rect);
-  }
-
+  PhysicalRect rect = GetLayoutObject().PhysicalVisualOverflowRect();
   if (GetLayoutObject().IsEffectiveRootScroller() || IsRootLayer()) {
     rect.Unite(
         PhysicalRect(rect.offset, GetLayoutObject().View()->ViewRect().size));
   }
-
   return rect;
 }
 
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
index 48ae0146..e3d58f8 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -113,13 +113,11 @@
 }  // namespace
 
 static LayoutRect LocalToAbsolute(const LayoutBox& box, LayoutRect rect) {
-  return box.LocalToAbsoluteRect(PhysicalRectToBeNoop(rect), kUseTransforms)
-      .ToLayoutRect();
+  return box.LocalToAbsoluteRect(PhysicalRectToBeNoop(rect)).ToLayoutRect();
 }
 
 static LayoutRect AbsoluteToLocal(const LayoutBox& box, LayoutRect rect) {
-  return box.AbsoluteToLocalRect(PhysicalRectToBeNoop(rect), kUseTransforms)
-      .ToLayoutRect();
+  return box.AbsoluteToLocalRect(PhysicalRectToBeNoop(rect)).ToLayoutRect();
 }
 
 PaintLayerScrollableAreaRareData::PaintLayerScrollableAreaRareData() = default;
@@ -1798,8 +1796,8 @@
   if (!GetLayoutBox()->CanResize())
     return false;
 
-  IntPoint local_point = RoundedIntPoint(GetLayoutBox()->AbsoluteToLocalPoint(
-      PhysicalOffset(absolute_point), kUseTransforms));
+  IntPoint local_point = RoundedIntPoint(
+      GetLayoutBox()->AbsoluteToLocalPoint(PhysicalOffset(absolute_point)));
   IntRect local_bounds(IntPoint(), Layer()->PixelSnappedSize());
   return ResizerCornerRect(local_bounds, resizer_hit_test_type)
       .Contains(local_point);
@@ -1929,8 +1927,8 @@
   if (GetLayoutBox()->ShouldPlaceBlockDirectionScrollbarOnLogicalLeft())
     element_size.SetWidth(0);
   IntPoint resizer_point = IntPoint(element_size);
-  IntPoint local_point = RoundedIntPoint(GetLayoutBox()->AbsoluteToLocalPoint(
-      PhysicalOffset(absolute_point), kUseTransforms));
+  IntPoint local_point = RoundedIntPoint(
+      GetLayoutBox()->AbsoluteToLocalPoint(PhysicalOffset(absolute_point)));
   return local_point - resizer_point;
 }
 
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
index ae739f8..9123ffd 100644
--- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -2034,14 +2034,8 @@
     const LayoutBox& box,
     const PhysicalRect& local_rect,
     const PaintLayer& ancestor_layer) {
-  // TODO(wangxianzhu): Use LocalToAncestorPoint() when it supports ignoring
-  // transforms.
-  TransformState transform_state(TransformState::kApplyTransformDirection,
-                                 FloatPoint(local_rect.offset));
-  box.MapLocalToAncestor(&ancestor_layer.GetLayoutObject(), transform_state, 0);
-  transform_state.Flatten();
-  return PhysicalRect::EnclosingRect(
-      FloatRect(transform_state.LastPlanarPoint(), FloatSize(local_rect.size)));
+  return box.LocalToAncestorRect(local_rect, &ancestor_layer.GetLayoutObject(),
+                                 kIgnoreTransforms);
 }
 
 static bool IsRepeatingTableSection(const LayoutObject& object) {
@@ -2155,15 +2149,9 @@
     return PaintOffsetInPaginationContainer(*object.ContainingBlock(),
                                             enclosing_pagination_layer);
   }
-
-  // TODO(wangxianzhu): Use LocalToAncestorPoint() when it supports ignoring
-  // transforms.
-  TransformState transform_state(TransformState::kApplyTransformDirection,
-                                 FloatPoint());
-  object.MapLocalToAncestor(&enclosing_pagination_layer.GetLayoutObject(),
-                            transform_state);
-  transform_state.Flatten();
-  return PhysicalOffset::FromFloatPointRound(transform_state.LastPlanarPoint());
+  return object.LocalToAncestorPoint(
+      PhysicalOffset(), &enclosing_pagination_layer.GetLayoutObject(),
+      kIgnoreTransforms);
 }
 
 void FragmentPaintPropertyTreeBuilder::UpdatePaintOffset() {
diff --git a/third_party/blink/renderer/core/timing/performance.cc b/third_party/blink/renderer/core/timing/performance.cc
index 4e93cab..2bd82de 100644
--- a/third_party/blink/renderer/core/timing/performance.cc
+++ b/third_party/blink/renderer/core/timing/performance.cc
@@ -33,6 +33,7 @@
 
 #include <algorithm>
 #include "base/metrics/histogram_macros.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/bindings/core/v8/string_or_performance_measure_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h"
 #include "third_party/blink/renderer/core/dom/document.h"
@@ -55,6 +56,9 @@
 #include "third_party/blink/renderer/core/timing/performance_observer.h"
 #include "third_party/blink/renderer/core/timing/performance_resource_timing.h"
 #include "third_party/blink/renderer/core/timing/performance_user_timing.h"
+#include "third_party/blink/renderer/core/timing/profiler.h"
+#include "third_party/blink/renderer/core/timing/profiler_group.h"
+#include "third_party/blink/renderer/core/timing/profiler_init_options.h"
 #include "third_party/blink/renderer/core/timing/time_clamper.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h"
@@ -892,6 +896,23 @@
   GetUserTiming().ClearMeasures(measure_name);
 }
 
+ScriptPromise Performance::profile(ScriptState* script_state,
+                                   const ProfilerInitOptions* options,
+                                   ExceptionState& exception_state) {
+  DCHECK(RuntimeEnabledFeatures::ExperimentalJSProfilerEnabled(
+      ExecutionContext::From(script_state)));
+
+  auto* profiler_group = ProfilerGroup::From(script_state->GetIsolate());
+  DCHECK(profiler_group);
+
+  auto* profiler = profiler_group->CreateProfiler(
+      script_state, *options, time_origin_, exception_state);
+  if (exception_state.HadException())
+    return ScriptPromise::Reject(script_state, exception_state);
+
+  return ScriptPromise::Cast(script_state, ToV8(profiler, script_state));
+}
+
 void Performance::RegisterPerformanceObserver(PerformanceObserver& observer) {
   observer_filter_options_ |= observer.FilterOptions();
   observers_.insert(&observer);
diff --git a/third_party/blink/renderer/core/timing/performance.h b/third_party/blink/renderer/core/timing/performance.h
index 1e692b1..569c1d5 100644
--- a/third_party/blink/renderer/core/timing/performance.h
+++ b/third_party/blink/renderer/core/timing/performance.h
@@ -64,8 +64,10 @@
 class PerformanceNavigation;
 class PerformanceObserver;
 class PerformanceTiming;
+class ProfilerInitOptions;
 class ResourceResponse;
 class ResourceTimingInfo;
+class ScriptPromise;
 class ScriptState;
 class ScriptValue;
 class SecurityOrigin;
@@ -250,6 +252,10 @@
 
   void clearMeasures(const AtomicString& measure_name);
 
+  ScriptPromise profile(ScriptState*,
+                        const ProfilerInitOptions*,
+                        ExceptionState&);
+
   void UnregisterPerformanceObserver(PerformanceObserver&);
   void RegisterPerformanceObserver(PerformanceObserver&);
   void UpdatePerformanceObserverFilterOptions();
diff --git a/third_party/blink/renderer/core/timing/performance.idl b/third_party/blink/renderer/core/timing/performance.idl
index 496ef9f..d8daffc 100644
--- a/third_party/blink/renderer/core/timing/performance.idl
+++ b/third_party/blink/renderer/core/timing/performance.idl
@@ -94,5 +94,9 @@
     // https://groups.google.com/a/chromium.org/d/msg/blink-dev/g5YRCGpC9vs/b4OJz71NmPwJ
     [Exposed=Window, Measure] readonly attribute MemoryInfo memory;
 
+    // JS Self-Profiling API
+    // https://github.com/WICG/js-self-profiling/
+    [CallWith=ScriptState, RuntimeEnabled=ExperimentalJSProfiler, RaisesException] Promise<Profiler> profile(ProfilerInitOptions options);
+
     [CallWith=ScriptState, ImplementedAs=toJSONForBinding] object toJSON();
 };
diff --git a/third_party/blink/renderer/devtools/front_end/console/ConsoleView.js b/third_party/blink/renderer/devtools/front_end/console/ConsoleView.js
index 3b938c3..7600d808 100644
--- a/third_party/blink/renderer/devtools/front_end/console/ConsoleView.js
+++ b/third_party/blink/renderer/devtools/front_end/console/ConsoleView.js
@@ -924,35 +924,8 @@
 
   _registerShortcuts() {
     this._shortcuts = {};
-
-    const shortcut = UI.KeyboardShortcut;
-    const section = UI.shortcutsScreen.section(Common.UIString('Console'));
-
-    const shortcutL = shortcut.makeDescriptor('l', UI.KeyboardShortcut.Modifiers.Ctrl);
-    let keys = [shortcutL];
-    if (Host.isMac()) {
-      const shortcutK = shortcut.makeDescriptor('k', UI.KeyboardShortcut.Modifiers.Meta);
-      keys.unshift(shortcutK);
-    }
-    section.addAlternateKeys(keys, Common.UIString('Clear console'));
-
-    keys = [shortcut.makeDescriptor(shortcut.Keys.Tab), shortcut.makeDescriptor(shortcut.Keys.Right)];
-    section.addRelatedKeys(keys, Common.UIString('Accept suggestion'));
-
-    const shortcutU = shortcut.makeDescriptor('u', UI.KeyboardShortcut.Modifiers.Ctrl);
-    this._shortcuts[shortcutU.key] = this._clearPromptBackwards.bind(this);
-    section.addAlternateKeys([shortcutU], Common.UIString('Clear console prompt'));
-
-    keys = [shortcut.makeDescriptor(shortcut.Keys.Down), shortcut.makeDescriptor(shortcut.Keys.Up)];
-    section.addRelatedKeys(keys, Common.UIString('Next/previous line'));
-
-    if (Host.isMac()) {
-      keys =
-          [shortcut.makeDescriptor('N', shortcut.Modifiers.Alt), shortcut.makeDescriptor('P', shortcut.Modifiers.Alt)];
-      section.addRelatedKeys(keys, Common.UIString('Next/previous command'));
-    }
-
-    section.addKey(shortcut.makeDescriptor(shortcut.Keys.Enter), Common.UIString('Execute command'));
+    this._shortcuts[UI.KeyboardShortcut.makeKey('u', UI.KeyboardShortcut.Modifiers.Ctrl)] =
+        this._clearPromptBackwards.bind(this);
   }
 
   _clearPromptBackwards() {
diff --git a/third_party/blink/renderer/devtools/front_end/ui/ShortcutsScreen.js b/third_party/blink/renderer/devtools/front_end/ui/ShortcutsScreen.js
index 9bcd4f0..45b955f58 100644
--- a/third_party/blink/renderer/devtools/front_end/ui/ShortcutsScreen.js
+++ b/third_party/blink/renderer/devtools/front_end/ui/ShortcutsScreen.js
@@ -57,6 +57,7 @@
         UI.shortcutRegistry.shortcutDescriptorsForAction('elements.edit-as-html'),
         Common.UIString('Toggle edit as HTML'));
 
+    // Styles pane
     const stylesPaneSection = UI.shortcutsScreen.section(Common.UIString('Styles Pane'));
 
     const nextPreviousProperty = UI.ShortcutsScreen.ElementsPanelShortcuts.NextProperty.concat(
@@ -83,118 +84,143 @@
     stylesPaneSection.addAlternateKeys(
         UI.ShortcutsScreen.ElementsPanelShortcuts.DecrementBy01, Common.UIString('Decrement by %f', 0.1));
 
-    // Debugger
-    let section = UI.shortcutsScreen.section(Common.UIString('Debugger'));
+    // Console
+    const consoleSection = UI.shortcutsScreen.section(Common.UIString('Console'));
 
-    section.addAlternateKeys(
+    consoleSection.addAlternateKeys(
+        UI.shortcutRegistry.shortcutDescriptorsForAction('console.clear'), Common.UIString('Clear console'));
+    consoleSection.addRelatedKeys(
+        UI.ShortcutsScreen.ConsolePanelShortcuts.AcceptSuggestion, Common.UIString('Accept suggestion'));
+    consoleSection.addAlternateKeys(
+        UI.ShortcutsScreen.ConsolePanelShortcuts.ClearConsolePrompt, Common.UIString('Clear console prompt'));
+    consoleSection.addRelatedKeys(
+        UI.ShortcutsScreen.ConsolePanelShortcuts.NextPreviousLine, Common.UIString('Next/previous line'));
+
+    if (Host.isMac()) {
+      consoleSection.addRelatedKeys(
+          UI.ShortcutsScreen.ConsolePanelShortcuts.NextPreviousCommand, Common.UIString('Next/previous command'));
+    }
+
+    consoleSection.addKey(UI.ShortcutsScreen.ConsolePanelShortcuts.ExecuteCommand, Common.UIString('Execute command'));
+
+    // Debugger
+    const debuggerSection = UI.shortcutsScreen.section(Common.UIString('Debugger'));
+
+    debuggerSection.addAlternateKeys(
         UI.shortcutRegistry.shortcutDescriptorsForAction('debugger.toggle-pause'), Common.UIString('Pause/ Continue'));
-    section.addAlternateKeys(
+    debuggerSection.addAlternateKeys(
         UI.shortcutRegistry.shortcutDescriptorsForAction('debugger.step-over'), Common.UIString('Step over'));
-    section.addAlternateKeys(
+    debuggerSection.addAlternateKeys(
         UI.shortcutRegistry.shortcutDescriptorsForAction('debugger.step-into'), Common.UIString('Step into'));
-    section.addAlternateKeys(
+    debuggerSection.addAlternateKeys(
         UI.shortcutRegistry.shortcutDescriptorsForAction('debugger.step-out'), Common.UIString('Step out'));
 
     const nextAndPrevFrameKeys =
         UI.shortcutRegistry.shortcutDescriptorsForAction('debugger.next-call-frame')
             .concat(UI.shortcutRegistry.shortcutDescriptorsForAction('debugger.previous-call-frame'));
-    section.addRelatedKeys(nextAndPrevFrameKeys, Common.UIString('Next/previous call frame'));
+    debuggerSection.addRelatedKeys(nextAndPrevFrameKeys, Common.UIString('Next/previous call frame'));
 
-    section.addAlternateKeys(
+    debuggerSection.addAlternateKeys(
         UI.ShortcutsScreen.SourcesPanelShortcuts.EvaluateSelectionInConsole,
         Common.UIString('Evaluate selection in console'));
-    section.addAlternateKeys(
+    debuggerSection.addAlternateKeys(
         UI.ShortcutsScreen.SourcesPanelShortcuts.AddSelectionToWatch, Common.UIString('Add selection to watch'));
-    section.addAlternateKeys(
+    debuggerSection.addAlternateKeys(
         UI.shortcutRegistry.shortcutDescriptorsForAction('debugger.toggle-breakpoint'),
         Common.UIString('Toggle breakpoint'));
-    section.addAlternateKeys(
+    debuggerSection.addAlternateKeys(
         UI.shortcutRegistry.shortcutDescriptorsForAction('debugger.toggle-breakpoint-enabled'),
         Common.UIString('Toggle breakpoint enabled'));
-    section.addAlternateKeys(
+    debuggerSection.addAlternateKeys(
         UI.shortcutRegistry.shortcutDescriptorsForAction('debugger.toggle-breakpoints-active'),
         Common.UIString('Toggle all breakpoints'));
 
     // Editing
-    section = UI.shortcutsScreen.section(Common.UIString('Text Editor'));
-    section.addAlternateKeys(
+    const editingSection = UI.shortcutsScreen.section(Common.UIString('Text Editor'));
+
+    editingSection.addAlternateKeys(
         UI.shortcutRegistry.shortcutDescriptorsForAction('sources.go-to-member'), Common.UIString('Go to member'));
-    section.addAlternateKeys(
+    editingSection.addAlternateKeys(
         UI.ShortcutsScreen.SourcesPanelShortcuts.ToggleAutocompletion, Common.UIString('Autocompletion'));
-    section.addAlternateKeys(
+    editingSection.addAlternateKeys(
         UI.shortcutRegistry.shortcutDescriptorsForAction('sources.go-to-line'), Common.UIString('Go to line'));
-    section.addAlternateKeys(
+    editingSection.addAlternateKeys(
         UI.shortcutRegistry.shortcutDescriptorsForAction('sources.jump-to-previous-location'),
         Common.UIString('Jump to previous editing location'));
-    section.addAlternateKeys(
+    editingSection.addAlternateKeys(
         UI.shortcutRegistry.shortcutDescriptorsForAction('sources.jump-to-next-location'),
         Common.UIString('Jump to next editing location'));
-    section.addAlternateKeys(UI.ShortcutsScreen.SourcesPanelShortcuts.ToggleComment, Common.UIString('Toggle comment'));
-    section.addAlternateKeys(
+    editingSection.addAlternateKeys(
+        UI.ShortcutsScreen.SourcesPanelShortcuts.ToggleComment, Common.UIString('Toggle comment'));
+    editingSection.addAlternateKeys(
         UI.ShortcutsScreen.SourcesPanelShortcuts.IncreaseCSSUnitByOne, Common.UIString('Increment CSS unit by 1'));
-    section.addAlternateKeys(
+    editingSection.addAlternateKeys(
         UI.ShortcutsScreen.SourcesPanelShortcuts.DecreaseCSSUnitByOne, Common.UIString('Decrement CSS unit by 1'));
-    section.addAlternateKeys(
+    editingSection.addAlternateKeys(
         UI.ShortcutsScreen.SourcesPanelShortcuts.IncreaseCSSUnitByTen, Common.UIString('Increment CSS unit by 10'));
-    section.addAlternateKeys(
+    editingSection.addAlternateKeys(
         UI.ShortcutsScreen.SourcesPanelShortcuts.DecreaseCSSUnitByTen, Common.UIString('Decrement CSS unit by 10'));
-    section.addAlternateKeys(
+    editingSection.addAlternateKeys(
         UI.ShortcutsScreen.SourcesPanelShortcuts.SelectNextOccurrence, Common.UIString('Select next occurrence'));
-    section.addAlternateKeys(UI.ShortcutsScreen.SourcesPanelShortcuts.SoftUndo, Common.UIString('Soft undo'));
-    section.addAlternateKeys(
+    editingSection.addAlternateKeys(UI.ShortcutsScreen.SourcesPanelShortcuts.SoftUndo, Common.UIString('Soft undo'));
+    editingSection.addAlternateKeys(
         UI.ShortcutsScreen.SourcesPanelShortcuts.GotoMatchingBracket, Common.UIString('Go to matching bracket'));
-    section.addAlternateKeys(
+    editingSection.addAlternateKeys(
         UI.shortcutRegistry.shortcutDescriptorsForAction('sources.close-editor-tab'),
         Common.UIString('Close editor tab'));
-    section.addAlternateKeys(
+    editingSection.addAlternateKeys(
         UI.shortcutRegistry.shortcutDescriptorsForAction('sources.switch-file'),
         Common.UIString('Switch between files with the same name and different extensions.'));
 
     // Performance panel
-    section = UI.shortcutsScreen.section(Common.UIString('Performance Panel'));
-    section.addAlternateKeys(
+    const performanceSection = UI.shortcutsScreen.section(Common.UIString('Performance Panel'));
+
+    performanceSection.addAlternateKeys(
         UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.toggle-recording'),
         Common.UIString('Start/stop recording'));
-    section.addAlternateKeys(
+    performanceSection.addAlternateKeys(
         UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.record-reload'),
         Common.UIString('Record page reload'));
-    section.addAlternateKeys(
+    performanceSection.addAlternateKeys(
         UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.save-to-file'), Common.UIString('Save profile'));
-    section.addAlternateKeys(
+    performanceSection.addAlternateKeys(
         UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.load-from-file'), Common.UIString('Load profile'));
-    section.addRelatedKeys(
+    performanceSection.addRelatedKeys(
         UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.jump-to-previous-frame')
             .concat(UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.jump-to-next-frame')),
         Common.UIString('Jump to previous/next frame'));
-    section.addRelatedKeys(
+    performanceSection.addRelatedKeys(
         UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.show-history'),
         Common.UIString('Pick a recording from history'));
-    section.addRelatedKeys(
+    performanceSection.addRelatedKeys(
         UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.previous-recording')
             .concat(UI.shortcutRegistry.shortcutDescriptorsForAction('timeline.next-recording')),
         Common.UIString('Show previous/next recording'));
 
     // Memory panel
-    section = UI.shortcutsScreen.section(Common.UIString('Memory Panel'));
-    section.addAlternateKeys(
+    const memorySection = UI.shortcutsScreen.section(Common.UIString('Memory Panel'));
+
+    memorySection.addAlternateKeys(
         UI.shortcutRegistry.shortcutDescriptorsForAction('profiler.heap-toggle-recording'),
         Common.UIString('Start/stop recording'));
 
     // Layers panel
-    section = UI.shortcutsScreen.section(Common.UIString('Layers Panel'));
-    section.addAlternateKeys(UI.ShortcutsScreen.LayersPanelShortcuts.ResetView, Common.UIString('Reset view'));
-    section.addAlternateKeys(UI.ShortcutsScreen.LayersPanelShortcuts.PanMode, Common.UIString('Switch to pan mode'));
-    section.addAlternateKeys(
+    const layersSection = UI.shortcutsScreen.section(Common.UIString('Layers Panel'));
+
+    layersSection.addAlternateKeys(UI.ShortcutsScreen.LayersPanelShortcuts.ResetView, Common.UIString('Reset view'));
+    layersSection.addAlternateKeys(
+        UI.ShortcutsScreen.LayersPanelShortcuts.PanMode, Common.UIString('Switch to pan mode'));
+    layersSection.addAlternateKeys(
         UI.ShortcutsScreen.LayersPanelShortcuts.RotateMode, Common.UIString('Switch to rotate mode'));
-    section.addAlternateKeys(
+    layersSection.addAlternateKeys(
         UI.ShortcutsScreen.LayersPanelShortcuts.TogglePanRotate,
         Common.UIString('Temporarily toggle pan/rotate mode while held'));
-    section.addAlternateKeys(UI.ShortcutsScreen.LayersPanelShortcuts.ZoomIn, Common.UIString('Zoom in'));
-    section.addAlternateKeys(UI.ShortcutsScreen.LayersPanelShortcuts.ZoomOut, Common.UIString('Zoom out'));
-    section.addRelatedKeys(
+    layersSection.addAlternateKeys(UI.ShortcutsScreen.LayersPanelShortcuts.ZoomIn, Common.UIString('Zoom in'));
+    layersSection.addAlternateKeys(UI.ShortcutsScreen.LayersPanelShortcuts.ZoomOut, Common.UIString('Zoom out'));
+    layersSection.addRelatedKeys(
         UI.ShortcutsScreen.LayersPanelShortcuts.Up.concat(UI.ShortcutsScreen.LayersPanelShortcuts.Down),
         Common.UIString('Pan or rotate up/down'));
-    section.addRelatedKeys(
+    layersSection.addRelatedKeys(
         UI.ShortcutsScreen.LayersPanelShortcuts.Left.concat(UI.ShortcutsScreen.LayersPanelShortcuts.Right),
         Common.UIString('Pan or rotate left/right'));
   }
@@ -402,6 +428,27 @@
   DecrementBy01: [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Down, UI.KeyboardShortcut.Modifiers.Alt)]
 };
 
+UI.ShortcutsScreen.ConsolePanelShortcuts = {
+  AcceptSuggestion: [
+    UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Tab),
+    UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Right)
+  ],
+
+  ClearConsolePrompt: [UI.KeyboardShortcut.makeDescriptor('u', UI.KeyboardShortcut.Modifiers.Ctrl)],
+
+  ExecuteCommand: UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Enter),
+
+  NextPreviousLine: [
+    UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Down),
+    UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Up)
+  ],
+
+  NextPreviousCommand: [
+    UI.KeyboardShortcut.makeDescriptor('N', UI.KeyboardShortcut.Modifiers.Alt),
+    UI.KeyboardShortcut.makeDescriptor('P', UI.KeyboardShortcut.Modifiers.Alt)
+  ],
+};
+
 UI.ShortcutsScreen.SourcesPanelShortcuts = {
   SelectNextOccurrence: [UI.KeyboardShortcut.makeDescriptor('d', UI.KeyboardShortcut.Modifiers.CtrlOrMeta)],
 
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
index 6b9fcaf..904f5dd2 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
@@ -360,7 +360,10 @@
   // We first map canvas coordinates to layout coordinates.
   LayoutRect path_rect(bounding_rect);
   LayoutRect canvas_rect = layout_box->PhysicalContentBoxRect().ToLayoutRect();
-  canvas_rect.MoveBy(layout_box->LocalToAbsolutePoint().ToLayoutPoint());
+  // TODO(fserb): Is this kIgnoreTransforms correct?
+  canvas_rect.MoveBy(
+      layout_box->LocalToAbsolutePoint(PhysicalOffset(), kIgnoreTransforms)
+          .ToLayoutPoint());
   path_rect.SetX(
       (canvas_rect.X() + path_rect.X() * canvas_rect.Width() / Width()));
   path_rect.SetY(
@@ -672,8 +675,8 @@
     return MakeGarbageCollected<HitTestCanvasResult>(String(), nullptr);
 
   LayoutBox* box = canvas()->GetLayoutBox();
-  FloatPoint local_pos(box->AbsoluteToLocalPoint(
-      PhysicalOffsetToBeNoop(location), kUseTransforms));
+  FloatPoint local_pos(
+      box->AbsoluteToLocalPoint(PhysicalOffsetToBeNoop(location)));
   if (box->StyleRef().HasBorder() || box->StyleRef().MayHavePadding())
     local_pos.Move(FloatSize(-box->PhysicalContentBoxOffset()));
   float scaleWidth = box->ContentWidth().ToFloat() == 0.0f
diff --git a/third_party/blink/renderer/modules/media_controls/resources/legacyMediaControls.css b/third_party/blink/renderer/modules/media_controls/resources/legacyMediaControls.css
index 4778042..a6ace7d5 100644
--- a/third_party/blink/renderer/modules/media_controls/resources/legacyMediaControls.css
+++ b/third_party/blink/renderer/modules/media_controls/resources/legacyMediaControls.css
@@ -638,6 +638,7 @@
     display: inline;
 
     background-color: rgba(0, 0, 0, 0.8);
+    padding: 2px 2px;
 }
 
 video::-webkit-media-text-track-region {
diff --git a/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css b/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css
index f0f269a..bce3c52 100644
--- a/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css
+++ b/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css
@@ -1189,6 +1189,7 @@
     display: inline;
 
     background-color: rgba(0, 0, 0, 0.8);
+    padding: 2px 2px;
 }
 
 video::-webkit-media-text-track-region {
diff --git a/third_party/blink/renderer/modules/xr/xr_input_source.cc b/third_party/blink/renderer/modules/xr/xr_input_source.cc
index 5ee644e..caaffb7 100644
--- a/third_party/blink/renderer/modules/xr/xr_input_source.cc
+++ b/third_party/blink/renderer/modules/xr/xr_input_source.cc
@@ -263,6 +263,11 @@
   pointer_transform_matrix_ = std::move(pointer_transform_matrix);
 }
 
+void XRInputSource::SetGamepadConnected(bool state) {
+  if (gamepad_)
+    gamepad_->SetConnected(state);
+}
+
 void XRInputSource::Trace(blink::Visitor* visitor) {
   visitor->Trace(session_);
   visitor->Trace(target_ray_space_);
diff --git a/third_party/blink/renderer/modules/xr/xr_input_source.h b/third_party/blink/renderer/modules/xr/xr_input_source.h
index 9704436..6c9230e 100644
--- a/third_party/blink/renderer/modules/xr/xr_input_source.h
+++ b/third_party/blink/renderer/modules/xr/xr_input_source.h
@@ -61,6 +61,7 @@
   uint32_t source_id() const { return source_id_; }
 
   void SetPointerTransformMatrix(std::unique_ptr<TransformationMatrix>);
+  void SetGamepadConnected(bool state);
 
   // Gamepad::Client
   GamepadHapticActuator* GetVibrationActuatorForGamepad(
diff --git a/third_party/blink/renderer/modules/xr/xr_session.cc b/third_party/blink/renderer/modules/xr/xr_session.cc
index e822371..1aef084 100644
--- a/third_party/blink/renderer/modules/xr/xr_session.cc
+++ b/third_party/blink/renderer/modules/xr/xr_session.cc
@@ -483,6 +483,10 @@
     canvas_input_provider_ = nullptr;
   }
 
+  for (auto& input_source : input_sources_.Values()) {
+    input_source->SetGamepadConnected(false);
+  }
+
   // If this session is the active immersive session, notify the frameProvider
   // that it's ended.
   if (xr_->frameProvider()->immersive_session() == this) {
@@ -767,17 +771,20 @@
       input_sources_.Set(input_state->source_id, input_source);
       added.push_back(input_source);
 
-      // If we previously had a stored_input_source
-      if (stored_input_source)
+      // If we previously had a stored_input_source, disconnect it's gamepad
+      // and mark that it was removed.
+      if (stored_input_source) {
+        stored_input_source->SetGamepadConnected(false);
         removed.push_back(stored_input_source);
+      }
     }
 
     input_source->active_frame_id = frame_id;
   }
 
-  // Remove any input sources that are inactive.  Note that this is done in
-  // two passes because HeapHashMap makes no guarantees about iterators on
-  // removal.
+  // Remove any input sources that are inactive, and disconnect their gamepad.
+  // Note that this is done in two passes because HeapHashMap makes no
+  // guarantees about iterators on removal.
   // We use a separate array of inactive sources here rather than just
   // processing removed, because if we replaced any input sources, they would
   // also be in removed, and we'd remove our newly added source.
@@ -785,6 +792,7 @@
   for (const auto& input_source : input_sources_.Values()) {
     if (input_source->active_frame_id != frame_id) {
       inactive_sources.push_back(input_source->source_id());
+      input_source->SetGamepadConnected(false);
       removed.push_back(input_source);
     }
   }
diff --git a/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc b/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc
index ec365a1..fe785b1 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.cc
@@ -147,7 +147,7 @@
 }
 
 std::unique_ptr<base::trace_event::TracedValue>
-ContentLayerClientImpl::TakeDebugInfo(cc::Layer* layer) {
+ContentLayerClientImpl::TakeDebugInfo(const cc::Layer* layer) {
   DCHECK_EQ(layer, cc_picture_layer_.get());
   auto traced_value = std::make_unique<base::trace_event::TracedValue>();
   traced_value->SetString("layer_name",
diff --git a/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h b/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h
index 584ba16..34808408 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h
+++ b/third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h
@@ -46,7 +46,7 @@
 
   // cc::LayerClient
   std::unique_ptr<base::trace_event::TracedValue> TakeDebugInfo(
-      cc::Layer*) override;
+      const cc::Layer*) override;
   void DidChangeScrollbarsHiddenIfOverlay(bool) override {}
 
   bool Matches(const PaintChunk& paint_chunk) const {
diff --git a/third_party/blink/renderer/platform/graphics/graphics_layer.cc b/third_party/blink/renderer/platform/graphics/graphics_layer.cc
index 96120a2..dd73e4f 100644
--- a/third_party/blink/renderer/platform/graphics/graphics_layer.cc
+++ b/third_party/blink/renderer/platform/graphics/graphics_layer.cc
@@ -645,7 +645,7 @@
     tracking->AddInvalidation(&client, client.DebugName(), rect, reason);
 }
 
-String GraphicsLayer::DebugName(cc::Layer* layer) const {
+String GraphicsLayer::DebugName(const cc::Layer* layer) const {
   if (layer->id() == contents_layer_id_)
     return "ContentsLayer for " + client_.DebugName(this);
 
@@ -986,7 +986,7 @@
 }
 
 std::unique_ptr<base::trace_event::TracedValue> GraphicsLayer::TakeDebugInfo(
-    cc::Layer* layer) {
+    const cc::Layer* layer) {
   auto traced_value = std::make_unique<base::trace_event::TracedValue>();
 
   traced_value->SetString(
diff --git a/third_party/blink/renderer/platform/graphics/graphics_layer.h b/third_party/blink/renderer/platform/graphics/graphics_layer.h
index ee45874..c8c2016 100644
--- a/third_party/blink/renderer/platform/graphics/graphics_layer.h
+++ b/third_party/blink/renderer/platform/graphics/graphics_layer.h
@@ -264,7 +264,7 @@
 
   // cc::LayerClient implementation.
   std::unique_ptr<base::trace_event::TracedValue> TakeDebugInfo(
-      cc::Layer*) override;
+      const cc::Layer*) override;
   void DidChangeScrollbarsHiddenIfOverlay(bool) override;
 
   PaintController& GetPaintController() const;
@@ -319,7 +319,7 @@
       const base::Optional<IntRect>& interest_rect = base::nullopt);
 
  protected:
-  String DebugName(cc::Layer*) const;
+  String DebugName(const cc::Layer*) const;
 
  private:
   friend class CompositedLayerMappingTest;
diff --git a/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc b/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc
index b128b44..17acefc 100644
--- a/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.cc
@@ -23,7 +23,13 @@
     Invalidate(PaintInvalidationReason::kUncacheable);
   }
 
-  String DebugName() const final { return "ForeignLayer"; }
+  String DebugName() const final {
+#if DCHECK_IS_ON()
+    return String("ForeignLayer for ") + layer_->DebugName().c_str();
+#else
+    return "ForeignLayer";
+#endif
+  }
 
   DOMNodeId OwnerNodeId() const final { return layer_->owner_node_id(); }
 
diff --git a/third_party/blink/renderer/platform/heap/heap_page.cc b/third_party/blink/renderer/platform/heap/heap_page.cc
index 23e6f41..7c8e3289 100644
--- a/third_party/blink/renderer/platform/heap/heap_page.cc
+++ b/third_party/blink/renderer/platform/heap/heap_page.cc
@@ -779,10 +779,10 @@
     size_t new_remaining_allocation_size) {
   remaining_allocation_size_ = new_remaining_allocation_size;
 
-  // Sync recorded allocated-object size:
-  //  - if previous alloc checkpoint is larger, allocation size has increased.
-  //  - if smaller, a net reduction in size since last call to
-  //  updateRemainingAllocationSize().
+  // Sync recorded allocated-object size using the recorded checkpoint in
+  // |remaining_allocation_size_|:
+  // - If checkpoint is larger, the allocated size has increased.
+  // - The allocated size has decreased, otherwise.
   if (last_remaining_allocation_size_ > remaining_allocation_size_) {
     GetThreadState()->Heap().IncreaseAllocatedObjectSize(
         last_remaining_allocation_size_ - remaining_allocation_size_);
@@ -793,15 +793,6 @@
   last_remaining_allocation_size_ = remaining_allocation_size_;
 }
 
-void NormalPageArena::UpdateRemainingAllocationSize() {
-  if (last_remaining_allocation_size_ > RemainingAllocationSize()) {
-    GetThreadState()->Heap().IncreaseAllocatedObjectSize(
-        last_remaining_allocation_size_ - RemainingAllocationSize());
-    last_remaining_allocation_size_ = RemainingAllocationSize();
-  }
-  DCHECK_EQ(last_remaining_allocation_size_, RemainingAllocationSize());
-}
-
 void NormalPageArena::SetAllocationPoint(Address point, size_t size) {
 #if DCHECK_IS_ON()
   if (point) {
@@ -811,13 +802,18 @@
     DCHECK_LE(size, static_cast<NormalPage*>(page)->PayloadSize());
   }
 #endif
+  // Free and clear the old linear allocation area.
   if (HasCurrentAllocationArea()) {
     AddToFreeList(CurrentAllocationPoint(), RemainingAllocationSize());
+    SetRemainingAllocationSize(0);
   }
-  UpdateRemainingAllocationSize();
+  // Set up a new linear allocation area.
   current_allocation_point_ = point;
   last_remaining_allocation_size_ = remaining_allocation_size_ = size;
   if (point) {
+    // Only, update allocated size and object start bitmap if the area is
+    // actually set up with a non-null address.
+    GetThreadState()->Heap().IncreaseAllocatedObjectSize(size);
     // Current allocation point can never be part of the object bitmap start
     // because the area can grow or shrink. Will be added back before a GC when
     // clearing the allocation point.
@@ -843,7 +839,6 @@
     return AllocateLargeObject(allocation_size, gc_info_index);
 
   // 2. Try to allocate from a free list.
-  UpdateRemainingAllocationSize();
   Address result = AllocateFromFreeList(allocation_size, gc_info_index);
   if (result)
     return result;
diff --git a/third_party/blink/renderer/platform/heap/heap_page.h b/third_party/blink/renderer/platform/heap/heap_page.h
index d973f70..44ad5116 100644
--- a/third_party/blink/renderer/platform/heap/heap_page.h
+++ b/third_party/blink/renderer/platform/heap/heap_page.h
@@ -885,7 +885,6 @@
   void SetAllocationPoint(Address, size_t);
 
   void SetRemainingAllocationSize(size_t);
-  void UpdateRemainingAllocationSize();
 
   FreeList free_list_;
   Address current_allocation_point_;
diff --git a/third_party/blink/renderer/platform/heap/heap_stats_collector.cc b/third_party/blink/renderer/platform/heap/heap_stats_collector.cc
index b95953a..9f969da 100644
--- a/third_party/blink/renderer/platform/heap/heap_stats_collector.cc
+++ b/third_party/blink/renderer/platform/heap/heap_stats_collector.cc
@@ -23,17 +23,12 @@
 void ThreadHeapStatsCollector::IncreaseAllocatedObjectSize(size_t bytes) {
   // The current GC may not have been started. This is ok as recording considers
   // the whole time range between garbage collections.
-  allocated_bytes_since_prev_gc_ += bytes;
+  allocated_bytes_since_prev_gc_ += static_cast<int64_t>(bytes);
 }
 
 void ThreadHeapStatsCollector::DecreaseAllocatedObjectSize(size_t bytes) {
   // See IncreaseAllocatedObjectSize.
-
-  // TODO(mlippautz): Fix underflow.
-  if (bytes > allocated_bytes_since_prev_gc_)
-    return;
-
-  allocated_bytes_since_prev_gc_ -= bytes;
+  allocated_bytes_since_prev_gc_ -= static_cast<int64_t>(bytes);
 }
 
 void ThreadHeapStatsCollector::AllocatedObjectSizeSafepoint() {
@@ -102,7 +97,11 @@
 }
 
 size_t ThreadHeapStatsCollector::object_size_in_bytes() const {
-  return previous().marked_bytes + allocated_bytes_since_prev_gc_;
+  DCHECK_GE(static_cast<int64_t>(previous().marked_bytes) +
+                allocated_bytes_since_prev_gc_,
+            0);
+  return static_cast<size_t>(static_cast<int64_t>(previous().marked_bytes) +
+                             allocated_bytes_since_prev_gc_);
 }
 
 double ThreadHeapStatsCollector::estimated_marking_time_in_seconds() const {
@@ -138,7 +137,7 @@
          scope_data[kLazySweepInIdle] + scope_data[kLazySweepOnAllocation];
 }
 
-size_t ThreadHeapStatsCollector::allocated_bytes_since_prev_gc() const {
+int64_t ThreadHeapStatsCollector::allocated_bytes_since_prev_gc() const {
   return allocated_bytes_since_prev_gc_;
 }
 
diff --git a/third_party/blink/renderer/platform/heap/heap_stats_collector.h b/third_party/blink/renderer/platform/heap/heap_stats_collector.h
index e8fd2fc..d7ff70c 100644
--- a/third_party/blink/renderer/platform/heap/heap_stats_collector.h
+++ b/third_party/blink/renderer/platform/heap/heap_stats_collector.h
@@ -258,7 +258,7 @@
   TimeDelta estimated_marking_time() const;
 
   size_t marked_bytes() const;
-  size_t allocated_bytes_since_prev_gc() const;
+  int64_t allocated_bytes_since_prev_gc() const;
 
   size_t allocated_space_bytes() const;
 
@@ -287,9 +287,8 @@
   Event previous_;
 
   // Allocated bytes since the last garbage collection. These bytes are reset
-  // after marking as they should be accounted in marked_bytes then (which are
-  // only available after sweeping though).
-  size_t allocated_bytes_since_prev_gc_ = 0;
+  // after marking as they are accounted in marked_bytes then.
+  int64_t allocated_bytes_since_prev_gc_ = 0;
 
   // Allocated space in bytes for all arenas.
   size_t allocated_space_bytes_ = 0;
diff --git a/third_party/blink/renderer/platform/heap/heap_test.cc b/third_party/blink/renderer/platform/heap/heap_test.cc
index 96ba65e..3b4ba8b 100644
--- a/third_party/blink/renderer/platform/heap/heap_test.cc
+++ b/third_party/blink/renderer/platform/heap/heap_test.cc
@@ -1712,6 +1712,8 @@
     persistents[persistent_count++] = new Persistent<DynamicallySizedObject>(
         DynamicallySizedObject::Create(size));
     slack += 4;
+    // The allocations in the loop may trigger GC with lazy sweeping.
+    CompleteSweepingIfNeeded();
     CheckWithSlack(base_level + total, heap.ObjectPayloadSizeForTesting(),
                    slack);
     if (test_pages_allocated) {
diff --git a/third_party/blink/renderer/platform/heap/heap_test_utilities.cc b/third_party/blink/renderer/platform/heap/heap_test_utilities.cc
index 2fb98c3..5c218ff 100644
--- a/third_party/blink/renderer/platform/heap/heap_test_utilities.cc
+++ b/third_party/blink/renderer/platform/heap/heap_test_utilities.cc
@@ -35,4 +35,9 @@
   }
 }
 
+void CompleteSweepingIfNeeded() {
+  if (ThreadState::Current()->IsSweepingInProgress())
+    ThreadState::Current()->CompleteSweep();
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/heap_test_utilities.h b/third_party/blink/renderer/platform/heap/heap_test_utilities.h
index 31af7270a..805cfb63 100644
--- a/third_party/blink/renderer/platform/heap/heap_test_utilities.h
+++ b/third_party/blink/renderer/platform/heap/heap_test_utilities.h
@@ -20,6 +20,7 @@
 void ConservativelyCollectGarbage(
     BlinkGC::SweepingType sweeping_type = BlinkGC::kEagerSweeping);
 void ClearOutOldGarbage();
+void CompleteSweepingIfNeeded();
 
 template <typename T>
 class ObjectWithCallbackBeforeInitializer
diff --git a/third_party/blink/renderer/platform/heap/thread_state.cc b/third_party/blink/renderer/platform/heap/thread_state.cc
index 224fc8e2..5ad96b6 100644
--- a/third_party/blink/renderer/platform/heap/thread_state.cc
+++ b/third_party/blink/renderer/platform/heap/thread_state.cc
@@ -396,7 +396,7 @@
   // If the allocated object size or the total memory size is small, don't
   // trigger a GC.
   if (heap_->stats_collector()->allocated_bytes_since_prev_gc() <
-          allocated_object_size_threshold ||
+          static_cast<int64_t>(allocated_object_size_threshold) ||
       TotalMemorySize() < total_memory_size_threshold)
     return false;
 
@@ -916,10 +916,13 @@
   TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"),
                  "BlinkGC.AllocatedSpaceKB",
                  CappedSizeInKB(stats_collector.allocated_space_bytes()));
-  TRACE_COUNTER1(
-      TRACE_DISABLED_BY_DEFAULT("blink_gc"),
-      "BlinkGC.AllocatedObjectSizeSincePreviousGCKB",
-      CappedSizeInKB(stats_collector.allocated_bytes_since_prev_gc()));
+  size_t allocated_bytes_since_prev_gc =
+      stats_collector.allocated_bytes_since_prev_gc() > 0
+          ? static_cast<size_t>(stats_collector.allocated_bytes_since_prev_gc())
+          : 0;
+  TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"),
+                 "BlinkGC.AllocatedObjectSizeSincePreviousGCKB",
+                 CappedSizeInKB(allocated_bytes_since_prev_gc));
   TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"),
                  "PartitionAlloc.TotalSizeOfCommittedPagesKB",
                  CappedSizeInKB(WTF::Partitions::TotalSizeOfCommittedPages()));
@@ -964,7 +967,8 @@
   constexpr size_t kMinObjectSizeForReportingThroughput = 1024 * 1024;
   if (WTF::TimeTicks::IsHighResolution() &&
       (event.object_size_in_bytes_before_sweeping >
-       kMinObjectSizeForReportingThroughput)) {
+       kMinObjectSizeForReportingThroughput) &&
+      !marking_duration.is_zero()) {
     DCHECK_GT(marking_duration.InMillisecondsF(), 0.0);
     // For marking throughput computation all marking steps, independent of
     // whether they are triggered from V8 or Blink, are relevant.
@@ -1633,8 +1637,13 @@
   if (ShouldVerifyMarking())
     VerifyMarking(marking_type);
 
-  ProcessHeap::DecreaseTotalAllocatedObjectSize(
-      Heap().stats_collector()->allocated_bytes_since_prev_gc());
+  if (Heap().stats_collector()->allocated_bytes_since_prev_gc() > 0) {
+    ProcessHeap::DecreaseTotalAllocatedObjectSize(static_cast<size_t>(
+        Heap().stats_collector()->allocated_bytes_since_prev_gc()));
+  } else {
+    ProcessHeap::IncreaseTotalAllocatedObjectSize(static_cast<size_t>(
+        -Heap().stats_collector()->allocated_bytes_since_prev_gc()));
+  }
   ProcessHeap::DecreaseTotalMarkedObjectSize(
       Heap().stats_collector()->previous().marked_bytes);
   ProcessHeap::IncreaseTotalMarkedObjectSize(marked_bytes);
diff --git a/third_party/blink/renderer/platform/heap/unified_heap_controller.cc b/third_party/blink/renderer/platform/heap/unified_heap_controller.cc
index 36480eae..ade76d5 100644
--- a/third_party/blink/renderer/platform/heap/unified_heap_controller.cc
+++ b/third_party/blink/renderer/platform/heap/unified_heap_controller.cc
@@ -182,7 +182,7 @@
 }
 
 void UnifiedHeapController::UpdateAllocatedObjectSize(
-    size_t allocated_bytes_since_prev_gc) {
+    int64_t allocated_bytes_since_prev_gc) {
   int64_t delta =
       allocated_bytes_since_prev_gc - old_allocated_bytes_since_prev_gc_;
   old_allocated_bytes_since_prev_gc_ = allocated_bytes_since_prev_gc;
diff --git a/third_party/blink/renderer/platform/heap/unified_heap_controller.h b/third_party/blink/renderer/platform/heap/unified_heap_controller.h
index 4190af0b..cc27a19e 100644
--- a/third_party/blink/renderer/platform/heap/unified_heap_controller.h
+++ b/third_party/blink/renderer/platform/heap/unified_heap_controller.h
@@ -48,7 +48,7 @@
   ThreadState* thread_state() const { return thread_state_; }
 
   // Forwarded from ThreadHeapStatsCollector.
-  void UpdateAllocatedObjectSize(size_t);
+  void UpdateAllocatedObjectSize(int64_t);
 
  private:
   static bool IsRootForNonTracingGCInternal(
diff --git a/third_party/blink/tools/blinkpy/common/net/git_cl.py b/third_party/blink/tools/blinkpy/common/net/git_cl.py
index 0491eaae..ca005ac 100644
--- a/third_party/blink/tools/blinkpy/common/net/git_cl.py
+++ b/third_party/blink/tools/blinkpy/common/net/git_cl.py
@@ -52,14 +52,11 @@
         self._cwd = cwd
         self._git_executable_name = Git.find_executable_name(host.executive, host.platform)
 
-    def run(self, args, return_stderr=False):
+    def run(self, args):
         """Runs git-cl with the given arguments and returns the output.
 
         Args:
             args: A list of arguments passed to `git cl`.
-            return_stderr: Whether to include stderr in the returned output (the
-                default is False because git-cl will show a warning when running
-                on Swarming bots with local git cache).
 
         Returns:
             A string (the output from git-cl).
@@ -67,7 +64,10 @@
         command = [self._git_executable_name, 'cl'] + args
         if self._auth_refresh_token_json and args[0] in _COMMANDS_THAT_TAKE_REFRESH_TOKEN:
             command += ['--auth-refresh-token-json', self._auth_refresh_token_json]
-        return self._host.executive.run_command(command, cwd=self._cwd, return_stderr=return_stderr)
+        # Suppress the stderr of git-cl because git-cl will show a warning when
+        # running on Swarming bots with local git cache.
+        return self._host.executive.run_command(
+            command, cwd=self._cwd, return_stderr=False, ignore_stderr=True)
 
     def trigger_try_jobs(self, builders, bucket=None):
         """Triggers try jobs on the given builders.
diff --git a/third_party/blink/tools/blinkpy/common/system/executive.py b/third_party/blink/tools/blinkpy/common/system/executive.py
index 0cf0369..3830b0a 100644
--- a/third_party/blink/tools/blinkpy/common/system/executive.py
+++ b/third_party/blink/tools/blinkpy/common/system/executive.py
@@ -311,13 +311,17 @@
                     error_handler=None,
                     return_exit_code=False,
                     return_stderr=True,
-                    decode_output=True, debug_logging=True):
+                    ignore_stderr=False,
+                    decode_output=True,
+                    debug_logging=True):
         """Popen wrapper for convenience and to work around python bugs."""
         assert isinstance(args, list) or isinstance(args, tuple)
         start_time = time.time()
 
+        assert not (return_stderr and ignore_stderr)
         stdin, string_to_communicate = self._compute_stdin(input)
-        stderr = self.STDOUT if return_stderr else None
+        stderr = self.STDOUT if return_stderr else (
+            self.DEVNULL if ignore_stderr else None)
 
         process = self.popen(args,
                              stdin=stdin,
diff --git a/third_party/blink/tools/blinkpy/common/system/executive_mock.py b/third_party/blink/tools/blinkpy/common/system/executive_mock.py
index aedb0fd0..ad7c0f1 100644
--- a/third_party/blink/tools/blinkpy/common/system/executive_mock.py
+++ b/third_party/blink/tools/blinkpy/common/system/executive_mock.py
@@ -123,6 +123,7 @@
                     error_handler=None,
                     return_exit_code=False,
                     return_stderr=True,
+                    ignore_stderr=False,
                     decode_output=True,
                     debug_logging=True):
         self._append_call(args, cwd=cwd, input=input, env=env)
@@ -156,7 +157,7 @@
         output = self._output
         if return_stderr:
             output += self._stderr
-        if decode_output and type(output) is not unicode:
+        if decode_output and not isinstance(output, unicode):
             output = output.decode('utf-8')
 
         return output
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 05e4d57..00022d5 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -249,10 +249,21 @@
 
 # Display locking, currently only available via a virtual test.
 crbug.com/882663 wpt_internal/display-lock [ Skip ]
+
+# Display locking, run highlight-display-locked.js only with display locking.
+crbug.com/882663 http/tests/devtools/elements/highlight/highlight-display-locked.js [ Skip ]
+crbug.com/882663 virtual/display-lock/http/tests/devtools/elements/highlight [ Skip ]
+Bug(none) virtual/display-lock/http/tests/devtools/elements/highlight/highlight-display-locked.js [ Pass ]
+
+# Display locking, run css-get-platform-fonts-display-locked.js only with display locking.
+crbug.com/882663 inspector-protocol/css/css-get-platform-fonts-display-locked.js [ Skip ]
+crbug.com/882663 virtual/display-lock/inspector-protocol/css [ Skip ]
+Bug(none) virtual/display-lock/inspector-protocol/css/css-get-platform-fonts-display-locked.js [ Pass ]
+
+# Display locking failures
 crbug.com/926276 virtual/display-lock/wpt_internal/display-lock/lock-after-append/nested-update.html [ Timeout ]
 crbug.com/926276 virtual/display-lock/wpt_internal/display-lock/lock-after-append/nested-update-and-commit.html [ Timeout ]
 crbug.com/955533 virtual/display-lock/wpt_internal/display-lock/sizing/overflow-auto-with-overflow.html [ Failure ]
-crbug.com/882663 http/tests/devtools/elements/highlight/highlight-display-locked.js [ Skip ]
 
 # Render throttling
 crbug.com/520170 fast/dom/timer-throttling-hidden-page.html [ Failure Pass ]
@@ -5723,3 +5734,9 @@
 
 # Sheriff 2019-05-27
 crbug.com/942411 [ Win ] http/tests/devtools/network/network-search.js [ Pass Timeout ]
+
+# Failing because of revert of If931c1faff528a87d8a78808f30225ebe2377072.
+crbug.com/966345 external/wpt/webvtt/rendering/cues-with-video/processing-model/2_tracks.html [ Failure ]
+crbug.com/966345 external/wpt/webvtt/rendering/cues-with-video/processing-model/3_tracks.html [ Failure ]
+crbug.com/966345 external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_normal_wrapped.html [ Failure ]
+crbug.com/966345 external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre-line_wrapped.html [ Failure ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites
index cebc681..6e6c6573 100644
--- a/third_party/blink/web_tests/VirtualTestSuites
+++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -669,6 +669,11 @@
     "args": ["--enable-blink-features=DisplayLocking"]
   },
   {
+    "prefix": "display-lock",
+    "base": "inspector-protocol/css",
+    "args": ["--enable-blink-features=DisplayLocking"]
+  },
+  {
     "prefix" : "autoupgrade-optionally-blockable-mixed-content",
     "base": "http/tests/mixed-autoupgrade/optionally",
     "args": ["--enable-features=AutoupgradeMixedContent<AU --force-fieldtrials=AU/G1 --force-fieldtrial-params=AU.G1:mode/optionally-blockable"]
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cue-rendering-empty-cue-ref.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cue-rendering-empty-cue-ref.html
deleted file mode 100644
index 837c4fd..0000000
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cue-rendering-empty-cue-ref.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!DOCTYPE html>
-<html class="reftest-wait">
-<title>Reference for track rendering with empty cue</title>
-<script src="/common/reftest-wait.js"></script>
-<style>
-html { overflow:hidden }
-body { margin:0 }
-.container {
-  display: inline-block;
-  position: relative;
-}
-</style>
-<div class="container">
-  <video width="320" height="180">
-    <source src="/media/white.webm" type="video/webm">
-    <source src="/media/white.mp4" type="video/mp4">
-    <script>
-      var video = document.querySelector("video");
-      video.addEventListener('playing', () => {
-        video.pause();
-        takeScreenshot();
-      }, { once: true});
-      video.play();
-    </script>
-  </video>
-</div>
-</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cue-rendering-empty-cue.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cue-rendering-empty-cue.html
index c2d3009..427189f 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cue-rendering-empty-cue.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cue-rendering-empty-cue.html
@@ -1,26 +1,16 @@
 <!DOCTYPE html>
-<html class="reftest-wait">
-<title>Track rendering with empty cue</title>
-<link rel="match" href="track-cue-rendering-empty-cue-ref.html">
-<style>
-html { overflow:hidden }
-body { margin:0 }
-</style>
-<script src="/common/reftest-wait.js"></script>
-<video width="320" height="180">
-  <source src="/media/white.webm" type="video/webm">
-  <source src="/media/white.mp4" type="video/mp4">
-  <script>
-    var video = document.querySelector("video");
-    var track = video.addTextTrack("captions", "regular captions track", "en");
-    track.addCue(new VTTCue(0, 4, ""));
-    track.mode = "showing";
+<title>Empty cues</title>
+<script src="/common/media.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+async_test(function(t) {
+    var video = document.createElement("video");
+    video.src = getVideoURI("/media/test");
+    video.addTextTrack("captions", "regular captions track", "en");
+    video.textTracks[0].addCue(new VTTCue(0, 4, ""));
 
-    video.addEventListener('playing', () => {
-      video.pause();
-      takeScreenshot();
-    }, { once: true});
+    video.onplaying = t.step_func_done();
     video.play();
-  </script>
-</video>
-</html>
\ No newline at end of file
+});
+</script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cue-rendering-line-doesnt-fit-ref.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cue-rendering-line-doesnt-fit-ref.html
index c4c14bc2..8354041 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cue-rendering-line-doesnt-fit-ref.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cue-rendering-line-doesnt-fit-ref.html
@@ -20,6 +20,7 @@
   background: green;
   color: green;
   font-size: 120px;
+  padding: 2px;
 }
 </style>
 <div class="container">
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cue-rendering-transformed-video-ref.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cue-rendering-transformed-video-ref.html
index c3ee804..39461350 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cue-rendering-transformed-video-ref.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-cue-rendering-transformed-video-ref.html
@@ -22,6 +22,7 @@
   background: green;
   color: green;
   font-size: 50px;
+  padding: 2px;
 }
 </style>
 <div class="container">
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-inherit_child-auto-child-none_touch.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-inherit_child-auto-child-none_touch.html
index f05aadf..bdd2809 100644
--- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-inherit_child-auto-child-none_touch.html
+++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_touch-action-inherit_child-auto-child-none_touch.html
@@ -92,7 +92,7 @@
             function run() {
                 var target0 = document.getElementById("target0");
                 var btnComplete = document.getElementById("btnComplete");
-                var clickIsReceived = false;
+                var actions_promise;
 
                 // Check if touch-action attribute works properly for embedded divs
                 // Scrollable-Parent, Child: `auto`, Grand-Child: `none`
@@ -103,7 +103,11 @@
                         assert_equals(target0.scrollLeft, 0, "scroll x offset should be 0 in the end of the test");
                         assert_equals(target0.scrollTop, 0, "scroll y offset should be 0 in the end of the test");
                     });
-                    clickIsReceived = true;
+
+                    // Make sure the test finishes after all the input actions are completed.
+                    actions_promise.then( () => {
+                      test_touchaction.done();
+                    });
                     updateDescriptionComplete();
                 });
 
@@ -112,15 +116,11 @@
                 });
 
                 // Inject touch inputs.
-                touchScrollInTarget(scrollTarget, 'down').then(function() {
-                    return touchScrollInTarget(scrollTarget, 'right');
+                actions_promise = touchScrollInTarget(scrollTarget, 'down');
+                actions_promise.then(function() {
+                    touchScrollInTarget(scrollTarget, 'right');
                 }).then(function() {
-                    return clickInTarget("touch", btnComplete);
-                }).then(function() {
-                    test_touchaction.step(function () {
-                        assert_true(clickIsReceived, "click should be received before the test finishes");
-                    }, "click should be received before the test finishes");
-                    test_touchaction.done();
+                    clickInTarget("touch", btnComplete);
                 });
             }
         </script>
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-helper.js b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-helper.js
index fde1c6f0..d859ac7 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-helper.js
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-helper.js
@@ -222,7 +222,11 @@
 }
 
 // Helper function for doing one round of offer/answer exchange
-// between two local peer connections
+// between two local peer connections.
+// Calls setRemoteDescription(offer/answer) before
+// setLocalDescription(offer/answer) to ensure the remote description
+// is set and candidates can be added before the local peer connection
+// starts generating candidates and ICE checks.
 async function doSignalingHandshake(localPc, remotePc, options={}) {
   let offer = await localPc.createOffer();
   // Modify offer if callback has been provided
@@ -230,9 +234,9 @@
     offer = await options.modifyOffer(offer);
   }
 
-  // Apply offer
-  await localPc.setLocalDescription(offer);
+  // Apply offer.
   await remotePc.setRemoteDescription(offer);
+  await localPc.setLocalDescription(offer);
 
   let answer = await remotePc.createAnswer();
   // Modify answer if callback has been provided
@@ -240,7 +244,7 @@
     answer = await options.modifyAnswer(answer);
   }
 
-  // Apply answer. Note: localPc should enter stable state first.
+  // Apply answer.
   await localPc.setRemoteDescription(answer);
   await remotePc.setLocalDescription(answer);
 }
diff --git a/third_party/blink/web_tests/fast/dom/Window/window-properties-performance-expected.txt b/third_party/blink/web_tests/fast/dom/Window/window-properties-performance-expected.txt
index 2a14d83..a378d728 100644
--- a/third_party/blink/web_tests/fast/dom/Window/window-properties-performance-expected.txt
+++ b/third_party/blink/web_tests/fast/dom/Window/window-properties-performance-expected.txt
@@ -29,6 +29,7 @@
 window.performance.onelementtimingbufferfull [null]
 window.performance.oneventtimingbufferfull [null]
 window.performance.onresourcetimingbufferfull [null]
+window.performance.profile [function]
 window.performance.removeEventListener [function]
 window.performance.setElementTimingBufferMaxSize [function]
 window.performance.setEventTimingBufferMaxSize [function]
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/http/tests/devtools/elements/highlight/highlight-node-vertical-rl-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/http/tests/devtools/elements/highlight/highlight-node-vertical-rl-expected.txt
new file mode 100644
index 0000000..0d88251
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/http/tests/devtools/elements/highlight/highlight-node-vertical-rl-expected.txt
@@ -0,0 +1,358 @@
+
+
+container{
+  "paths": [
+    {
+      "path": [
+        "M",
+        80,
+        50,
+        "L",
+        380,
+        50,
+        "L",
+        380,
+        350,
+        "L",
+        80,
+        350,
+        "Z"
+      ],
+      "fillColor": "rgba(255, 0, 0, 0)",
+      "outlineColor": "rgba(128, 0, 0, 0)",
+      "name": "content"
+    },
+    {
+      "path": [
+        "M",
+        80,
+        50,
+        "L",
+        380,
+        50,
+        "L",
+        380,
+        350,
+        "L",
+        80,
+        350,
+        "Z"
+      ],
+      "fillColor": "rgba(0, 255, 0, 0)",
+      "name": "padding"
+    },
+    {
+      "path": [
+        "M",
+        80,
+        50,
+        "L",
+        380,
+        50,
+        "L",
+        380,
+        350,
+        "L",
+        80,
+        350,
+        "Z"
+      ],
+      "fillColor": "rgba(0, 0, 255, 0)",
+      "name": "border"
+    },
+    {
+      "path": [
+        "M",
+        0,
+        0,
+        "L",
+        800,
+        0,
+        "L",
+        800,
+        420,
+        "L",
+        0,
+        420,
+        "Z"
+      ],
+      "fillColor": "rgba(255, 255, 255, 0)",
+      "name": "margin"
+    }
+  ],
+  "showRulers": true,
+  "showExtensionLines": true,
+  "elementInfo": {
+    "tagName": "div",
+    "idValue": "container",
+    "nodeWidth": "300",
+    "nodeHeight": "300"
+  }
+}
+child{
+  "paths": [
+    {
+      "path": [
+        "M",
+        220,
+        100,
+        "L",
+        320,
+        100,
+        "L",
+        320,
+        200,
+        "L",
+        220,
+        200,
+        "Z"
+      ],
+      "fillColor": "rgba(255, 0, 0, 0)",
+      "outlineColor": "rgba(128, 0, 0, 0)",
+      "name": "content"
+    },
+    {
+      "path": [
+        "M",
+        140,
+        50,
+        "L",
+        380,
+        50,
+        "L",
+        380,
+        270,
+        "L",
+        140,
+        270,
+        "Z"
+      ],
+      "fillColor": "rgba(0, 255, 0, 0)",
+      "name": "padding"
+    },
+    {
+      "path": [
+        "M",
+        140,
+        50,
+        "L",
+        380,
+        50,
+        "L",
+        380,
+        270,
+        "L",
+        140,
+        270,
+        "Z"
+      ],
+      "fillColor": "rgba(0, 0, 255, 0)",
+      "name": "border"
+    },
+    {
+      "path": [
+        "M",
+        140,
+        50,
+        "L",
+        380,
+        50,
+        "L",
+        380,
+        350,
+        "L",
+        140,
+        350,
+        "Z"
+      ],
+      "fillColor": "rgba(255, 255, 255, 0)",
+      "name": "margin"
+    }
+  ],
+  "showRulers": true,
+  "showExtensionLines": true,
+  "elementInfo": {
+    "tagName": "div",
+    "idValue": "child",
+    "nodeWidth": "240",
+    "nodeHeight": "220"
+  }
+}
+span{
+  "paths": [
+    {
+      "path": [
+        "M",
+        310,
+        100,
+        "L",
+        320,
+        100,
+        "L",
+        320,
+        170,
+        "L",
+        310,
+        170,
+        "Z"
+      ],
+      "fillColor": "rgba(255, 0, 0, 0)",
+      "outlineColor": "rgba(128, 0, 0, 0)",
+      "name": "content"
+    },
+    {
+      "path": [
+        "M",
+        310,
+        100,
+        "L",
+        320,
+        100,
+        "L",
+        320,
+        170,
+        "L",
+        310,
+        170,
+        "Z"
+      ],
+      "fillColor": "rgba(0, 255, 0, 0)",
+      "name": "padding"
+    },
+    {
+      "path": [
+        "M",
+        310,
+        100,
+        "L",
+        320,
+        100,
+        "L",
+        320,
+        170,
+        "L",
+        310,
+        170,
+        "Z"
+      ],
+      "fillColor": "rgba(0, 0, 255, 0)",
+      "name": "border"
+    },
+    {
+      "path": [
+        "M",
+        310,
+        100,
+        "L",
+        320,
+        100,
+        "L",
+        320,
+        170,
+        "L",
+        310,
+        170,
+        "Z"
+      ],
+      "fillColor": "rgba(255, 255, 255, 0)",
+      "name": "margin"
+    }
+  ],
+  "showRulers": true,
+  "showExtensionLines": true,
+  "elementInfo": {
+    "tagName": "span",
+    "idValue": "span",
+    "nodeWidth": "10",
+    "nodeHeight": "70"
+  }
+}
+TEXT{
+  "paths": [
+    {
+      "path": [
+        "M",
+        310,
+        100,
+        "L",
+        320,
+        100,
+        "L",
+        320,
+        170,
+        "L",
+        310,
+        170,
+        "Z"
+      ],
+      "fillColor": "rgba(255, 0, 0, 0)",
+      "outlineColor": "rgba(128, 0, 0, 0)",
+      "name": "content"
+    },
+    {
+      "path": [
+        "M",
+        310,
+        100,
+        "L",
+        320,
+        100,
+        "L",
+        320,
+        170,
+        "L",
+        310,
+        170,
+        "Z"
+      ],
+      "fillColor": "rgba(0, 255, 0, 0)",
+      "name": "padding"
+    },
+    {
+      "path": [
+        "M",
+        310,
+        100,
+        "L",
+        320,
+        100,
+        "L",
+        320,
+        170,
+        "L",
+        310,
+        170,
+        "Z"
+      ],
+      "fillColor": "rgba(0, 0, 255, 0)",
+      "name": "border"
+    },
+    {
+      "path": [
+        "M",
+        310,
+        100,
+        "L",
+        320,
+        100,
+        "L",
+        320,
+        170,
+        "L",
+        310,
+        170,
+        "Z"
+      ],
+      "fillColor": "rgba(255, 255, 255, 0)",
+      "name": "margin"
+    }
+  ],
+  "showRulers": true,
+  "showExtensionLines": true,
+  "elementInfo": {
+    "nodeWidth": "10",
+    "nodeHeight": "70",
+    "tagName": "#text"
+  }
+}
+
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-node-vertical-rl-expected.txt b/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-node-vertical-rl-expected.txt
new file mode 100644
index 0000000..19c8be8
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-node-vertical-rl-expected.txt
@@ -0,0 +1,358 @@
+
+
+container{
+  "paths": [
+    {
+      "path": [
+        "M",
+        80,
+        50,
+        "L",
+        380,
+        50,
+        "L",
+        380,
+        350,
+        "L",
+        80,
+        350,
+        "Z"
+      ],
+      "fillColor": "rgba(255, 0, 0, 0)",
+      "outlineColor": "rgba(128, 0, 0, 0)",
+      "name": "content"
+    },
+    {
+      "path": [
+        "M",
+        80,
+        50,
+        "L",
+        380,
+        50,
+        "L",
+        380,
+        350,
+        "L",
+        80,
+        350,
+        "Z"
+      ],
+      "fillColor": "rgba(0, 255, 0, 0)",
+      "name": "padding"
+    },
+    {
+      "path": [
+        "M",
+        80,
+        50,
+        "L",
+        380,
+        50,
+        "L",
+        380,
+        350,
+        "L",
+        80,
+        350,
+        "Z"
+      ],
+      "fillColor": "rgba(0, 0, 255, 0)",
+      "name": "border"
+    },
+    {
+      "path": [
+        "M",
+        0,
+        0,
+        "L",
+        440,
+        0,
+        "L",
+        440,
+        420,
+        "L",
+        0,
+        420,
+        "Z"
+      ],
+      "fillColor": "rgba(255, 255, 255, 0)",
+      "name": "margin"
+    }
+  ],
+  "showRulers": true,
+  "showExtensionLines": true,
+  "elementInfo": {
+    "tagName": "div",
+    "idValue": "container",
+    "nodeWidth": "300",
+    "nodeHeight": "300"
+  }
+}
+child{
+  "paths": [
+    {
+      "path": [
+        "M",
+        220,
+        100,
+        "L",
+        320,
+        100,
+        "L",
+        320,
+        200,
+        "L",
+        220,
+        200,
+        "Z"
+      ],
+      "fillColor": "rgba(255, 0, 0, 0)",
+      "outlineColor": "rgba(128, 0, 0, 0)",
+      "name": "content"
+    },
+    {
+      "path": [
+        "M",
+        140,
+        50,
+        "L",
+        380,
+        50,
+        "L",
+        380,
+        270,
+        "L",
+        140,
+        270,
+        "Z"
+      ],
+      "fillColor": "rgba(0, 255, 0, 0)",
+      "name": "padding"
+    },
+    {
+      "path": [
+        "M",
+        140,
+        50,
+        "L",
+        380,
+        50,
+        "L",
+        380,
+        270,
+        "L",
+        140,
+        270,
+        "Z"
+      ],
+      "fillColor": "rgba(0, 0, 255, 0)",
+      "name": "border"
+    },
+    {
+      "path": [
+        "M",
+        140,
+        50,
+        "L",
+        380,
+        50,
+        "L",
+        380,
+        350,
+        "L",
+        140,
+        350,
+        "Z"
+      ],
+      "fillColor": "rgba(255, 255, 255, 0)",
+      "name": "margin"
+    }
+  ],
+  "showRulers": true,
+  "showExtensionLines": true,
+  "elementInfo": {
+    "tagName": "div",
+    "idValue": "child",
+    "nodeWidth": "240",
+    "nodeHeight": "220"
+  }
+}
+span{
+  "paths": [
+    {
+      "path": [
+        "M",
+        310,
+        100,
+        "L",
+        320,
+        100,
+        "L",
+        320,
+        170,
+        "L",
+        310,
+        170,
+        "Z"
+      ],
+      "fillColor": "rgba(255, 0, 0, 0)",
+      "outlineColor": "rgba(128, 0, 0, 0)",
+      "name": "content"
+    },
+    {
+      "path": [
+        "M",
+        310,
+        100,
+        "L",
+        320,
+        100,
+        "L",
+        320,
+        170,
+        "L",
+        310,
+        170,
+        "Z"
+      ],
+      "fillColor": "rgba(0, 255, 0, 0)",
+      "name": "padding"
+    },
+    {
+      "path": [
+        "M",
+        310,
+        100,
+        "L",
+        320,
+        100,
+        "L",
+        320,
+        170,
+        "L",
+        310,
+        170,
+        "Z"
+      ],
+      "fillColor": "rgba(0, 0, 255, 0)",
+      "name": "border"
+    },
+    {
+      "path": [
+        "M",
+        310,
+        100,
+        "L",
+        320,
+        100,
+        "L",
+        320,
+        170,
+        "L",
+        310,
+        170,
+        "Z"
+      ],
+      "fillColor": "rgba(255, 255, 255, 0)",
+      "name": "margin"
+    }
+  ],
+  "showRulers": true,
+  "showExtensionLines": true,
+  "elementInfo": {
+    "tagName": "span",
+    "idValue": "span",
+    "nodeWidth": "10",
+    "nodeHeight": "70"
+  }
+}
+TEXT{
+  "paths": [
+    {
+      "path": [
+        "M",
+        310,
+        100,
+        "L",
+        320,
+        100,
+        "L",
+        320,
+        170,
+        "L",
+        310,
+        170,
+        "Z"
+      ],
+      "fillColor": "rgba(255, 0, 0, 0)",
+      "outlineColor": "rgba(128, 0, 0, 0)",
+      "name": "content"
+    },
+    {
+      "path": [
+        "M",
+        310,
+        100,
+        "L",
+        320,
+        100,
+        "L",
+        320,
+        170,
+        "L",
+        310,
+        170,
+        "Z"
+      ],
+      "fillColor": "rgba(0, 255, 0, 0)",
+      "name": "padding"
+    },
+    {
+      "path": [
+        "M",
+        310,
+        100,
+        "L",
+        320,
+        100,
+        "L",
+        320,
+        170,
+        "L",
+        310,
+        170,
+        "Z"
+      ],
+      "fillColor": "rgba(0, 0, 255, 0)",
+      "name": "border"
+    },
+    {
+      "path": [
+        "M",
+        310,
+        100,
+        "L",
+        320,
+        100,
+        "L",
+        320,
+        170,
+        "L",
+        310,
+        170,
+        "Z"
+      ],
+      "fillColor": "rgba(255, 255, 255, 0)",
+      "name": "margin"
+    }
+  ],
+  "showRulers": true,
+  "showExtensionLines": true,
+  "elementInfo": {
+    "nodeWidth": "10",
+    "nodeHeight": "70",
+    "tagName": "#text"
+  }
+}
+
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-node-vertical-rl.js b/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-node-vertical-rl.js
new file mode 100644
index 0000000..372151e8
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/devtools/elements/highlight/highlight-node-vertical-rl.js
@@ -0,0 +1,48 @@
+// Copyright 2019 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(`\n`);
+  await TestRunner.loadModule('elements_test_runner');
+  await TestRunner.loadModule('console_test_runner');
+  await TestRunner.showPanel('elements');
+  await TestRunner.loadHTML(`
+    <script src="/js-test-resources/ahem.js"></script>
+    <style>
+    body {
+      margin: 0;
+      font: 10px/10px Ahem;
+    }
+    #container {
+      margin: 50px 60px 70px 80px;
+      width: 300px;
+      height: 300px;
+      writing-mode: vertical-rl;
+    }
+    #child {
+      padding: 50px 60px 70px 80px;
+      width: 100px;
+      height: 100px;
+    }
+    </style>
+    <div id="container">
+      <div id="child">
+        <span id="span">ABCDEFG</span>
+      </div>
+    </div>
+  `);
+
+  await TestRunner.evaluateInPagePromise('');
+  function dumpHighlight(id) {
+    return new Promise(resolve => ElementsTestRunner.dumpInspectorHighlightJSON(id, resolve));
+  }
+  await dumpHighlight('container');
+  await dumpHighlight('child');
+  await dumpHighlight('span');
+
+  let textNode = await ElementsTestRunner.findNodePromise(node => node.nodeValue() == 'ABCDEFG');
+  let result = await TestRunner.OverlayAgent.getHighlightObjectForTest(textNode.id);
+  TestRunner.addResult('TEXT' + JSON.stringify(result, null, 2));
+  TestRunner.completeTest();
+})();
diff --git a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index f8a07ed..e0a33d6 100644
--- a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -1009,6 +1009,7 @@
     method mark
     method measure
     method now
+    method profile
     method setElementTimingBufferMaxSize
     method setEventTimingBufferMaxSize
     method setResourceTimingBufferSize
diff --git a/third_party/blink/web_tests/inspector-protocol/css/css-get-platform-fonts-display-locked-expected.txt b/third_party/blink/web_tests/inspector-protocol/css/css-get-platform-fonts-display-locked-expected.txt
new file mode 100644
index 0000000..7cfe6de
--- /dev/null
+++ b/third_party/blink/web_tests/inspector-protocol/css/css-get-platform-fonts-display-locked-expected.txt
@@ -0,0 +1,6 @@
+Test css.getPlatformFontsForNode method with display locking.
+
+Running test: testParent
+
+Running test: testChild
+
diff --git a/third_party/blink/web_tests/inspector-protocol/css/css-get-platform-fonts-display-locked.js b/third_party/blink/web_tests/inspector-protocol/css/css-get-platform-fonts-display-locked.js
new file mode 100644
index 0000000..bdedf2d
--- /dev/null
+++ b/third_party/blink/web_tests/inspector-protocol/css/css-get-platform-fonts-display-locked.js
@@ -0,0 +1,70 @@
+(async function(testRunner) {
+  var {page, session, dp} = await testRunner.startHTML(`
+<style>
+@font-face {
+    font-family: 'ahem';
+    src: url('${testRunner.url('./resources/Ahem.ttf')}');
+}
+#parent {
+  contain: style layout;
+  font-family: 'ahem';
+  background-color: gray;
+}
+#parent:first-letter {
+  font-family: 'Times New Roman';
+  font-size: 400%;
+  background-color: blue;
+}
+
+#parent:first-line {
+  font-family: 'Courier New';
+  background-color: yellow;
+}
+</style>
+
+<div id='parent'>
+7chars.<br>
+<span id='child'>Some line with 29 characters.</span>
+</div>
+`, 'Test css.getPlatformFontsForNode method with display locking.');
+
+  await session.evaluateAsync(async () => {
+    await document.getElementById("parent").displayLock.acquire({ timeout: Infinity });
+  });
+
+  var CSSHelper = await testRunner.loadScript('../resources/css-helper.js');
+  var cssHelper = new CSSHelper(testRunner, dp);
+
+  await dp.DOM.enable();
+  await dp.CSS.enable();
+
+  var documentNodeId = await cssHelper.requestDocumentNodeId();
+
+  testRunner.runTestSuite([
+    async function testParent(next) {
+      await platformFontsForElementWithSelector('#parent');
+    },
+    async function testChild(next) {
+      await platformFontsForElementWithSelector('#child');
+    },
+  ]);
+
+  async function platformFontsForElementWithSelector(selector) {
+    var nodeId = await cssHelper.requestNodeId(documentNodeId, selector);
+    var response = await dp.CSS.getPlatformFontsForNode({ nodeId });
+    var fonts = response.result.fonts;
+    fonts.sort((a, b) => b.glyphCount - a.glyphCount);
+    for (var i = 0; i < fonts.length; ++i)
+      fonts[i].familyName = '<Some-family-name-' + i + '>';
+    for (var i = 0; i < fonts.length; ++i) {
+      var lines = [
+        'Font #' + i,
+        '    name: ' + fonts[i].familyName,
+        '    glyphCount: ' + fonts[i].glyphCount,
+        '    isCustomFont: ' + fonts[i].isCustomFont
+      ];
+      testRunner.log(lines.join('\n'));
+    }
+  }
+});
+
diff --git a/third_party/blink/web_tests/media/track/track-cue-rendering-position-auto-expected.html b/third_party/blink/web_tests/media/track/track-cue-rendering-position-auto-expected.html
index 20b475f..90a2d9be 100644
--- a/third_party/blink/web_tests/media/track/track-cue-rendering-position-auto-expected.html
+++ b/third_party/blink/web_tests/media/track/track-cue-rendering-position-auto-expected.html
@@ -30,6 +30,7 @@
     background: green;
     color: green;
     font-size: 50px;
+    padding: 2px;
 }
 </style>
 <div class="container">
diff --git a/third_party/blink/web_tests/media/track/track-cue-rendering-position-auto-rtl-expected.html b/third_party/blink/web_tests/media/track/track-cue-rendering-position-auto-rtl-expected.html
index 74098ce..350837c 100644
--- a/third_party/blink/web_tests/media/track/track-cue-rendering-position-auto-rtl-expected.html
+++ b/third_party/blink/web_tests/media/track/track-cue-rendering-position-auto-rtl-expected.html
@@ -32,6 +32,7 @@
     background: green;
     color: green;
     font-size: 50px;
+    padding: 2px;
 }
 </style>
 <div class="container">
diff --git a/third_party/blink/web_tests/media/track/track-cue-rendering-with-padding.html b/third_party/blink/web_tests/media/track/track-cue-rendering-with-padding.html
index 70474ba..9ccce45 100644
--- a/third_party/blink/web_tests/media/track/track-cue-rendering-with-padding.html
+++ b/third_party/blink/web_tests/media/track/track-cue-rendering-with-padding.html
@@ -5,7 +5,7 @@
 <script src="../../resources/testharnessreport.js"></script>
 <style>
 video::-webkit-media-text-track-display {
-  padding: 10px;
+  padding: 15px;
 }
 </style>
 <video>
diff --git a/third_party/blink/web_tests/platform/linux/media/track/track-cue-rendering-horizontal-expected.png b/third_party/blink/web_tests/platform/linux/media/track/track-cue-rendering-horizontal-expected.png
index 744f01f..1c767b4 100644
--- a/third_party/blink/web_tests/platform/linux/media/track/track-cue-rendering-horizontal-expected.png
+++ b/third_party/blink/web_tests/platform/linux/media/track/track-cue-rendering-horizontal-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/media/track/track-cue-rendering-vertical-expected.png b/third_party/blink/web_tests/platform/linux/media/track/track-cue-rendering-vertical-expected.png
index 0fb28191..c53e8c5a 100644
--- a/third_party/blink/web_tests/platform/linux/media/track/track-cue-rendering-vertical-expected.png
+++ b/third_party/blink/web_tests/platform/linux/media/track/track-cue-rendering-vertical-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/video-surface-layer/media/track/track-cue-rendering-horizontal-expected.png b/third_party/blink/web_tests/platform/linux/virtual/video-surface-layer/media/track/track-cue-rendering-horizontal-expected.png
deleted file mode 100644
index 744f01f..0000000
--- a/third_party/blink/web_tests/platform/linux/virtual/video-surface-layer/media/track/track-cue-rendering-horizontal-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/video-surface-layer/media/track/track-cue-rendering-vertical-expected.png b/third_party/blink/web_tests/platform/linux/virtual/video-surface-layer/media/track/track-cue-rendering-vertical-expected.png
index 0fb28191..c53e8c5a 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/video-surface-layer/media/track/track-cue-rendering-vertical-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/video-surface-layer/media/track/track-cue-rendering-vertical-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/media/track/track-cue-rendering-vertical-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/media/track/track-cue-rendering-vertical-expected.png
index 9c2e12e..07055e21 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.10/media/track/track-cue-rendering-vertical-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.10/media/track/track-cue-rendering-vertical-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/video-surface-layer/media/track/track-cue-rendering-vertical-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/video-surface-layer/media/track/track-cue-rendering-vertical-expected.png
index 9c2e12e..07055e21 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/video-surface-layer/media/track/track-cue-rendering-vertical-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/video-surface-layer/media/track/track-cue-rendering-vertical-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/media/track/track-cue-rendering-vertical-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/media/track/track-cue-rendering-vertical-expected.png
index 08193f25..3a2ab97 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.11/media/track/track-cue-rendering-vertical-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.11/media/track/track-cue-rendering-vertical-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/virtual/video-surface-layer/media/track/track-cue-rendering-vertical-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/virtual/video-surface-layer/media/track/track-cue-rendering-vertical-expected.png
index 08193f25..3a2ab97 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.11/virtual/video-surface-layer/media/track/track-cue-rendering-vertical-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.11/virtual/video-surface-layer/media/track/track-cue-rendering-vertical-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/media/track/track-cue-rendering-horizontal-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/media/track/track-cue-rendering-horizontal-expected.png
index 38d844e..17b7f9d6 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.12/media/track/track-cue-rendering-horizontal-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.12/media/track/track-cue-rendering-horizontal-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/video-surface-layer/media/track/track-cue-rendering-horizontal-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/video-surface-layer/media/track/track-cue-rendering-horizontal-expected.png
index 38d844e..17b7f9d6 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/video-surface-layer/media/track/track-cue-rendering-horizontal-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/video-surface-layer/media/track/track-cue-rendering-horizontal-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/media/track/track-cue-rendering-horizontal-expected.png b/third_party/blink/web_tests/platform/mac/media/track/track-cue-rendering-horizontal-expected.png
index 112cac81..26a8ba6 100644
--- a/third_party/blink/web_tests/platform/mac/media/track/track-cue-rendering-horizontal-expected.png
+++ b/third_party/blink/web_tests/platform/mac/media/track/track-cue-rendering-horizontal-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/media/track/track-cue-rendering-vertical-expected.png b/third_party/blink/web_tests/platform/mac/media/track/track-cue-rendering-vertical-expected.png
index 86a37f3..015250c 100644
--- a/third_party/blink/web_tests/platform/mac/media/track/track-cue-rendering-vertical-expected.png
+++ b/third_party/blink/web_tests/platform/mac/media/track/track-cue-rendering-vertical-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/media/track/track-cue-rendering-horizontal-expected.png b/third_party/blink/web_tests/platform/win/media/track/track-cue-rendering-horizontal-expected.png
index 5a483e8..021412e 100644
--- a/third_party/blink/web_tests/platform/win/media/track/track-cue-rendering-horizontal-expected.png
+++ b/third_party/blink/web_tests/platform/win/media/track/track-cue-rendering-horizontal-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/media/track/track-cue-rendering-vertical-expected.png b/third_party/blink/web_tests/platform/win/media/track/track-cue-rendering-vertical-expected.png
index 2196206d..457955f 100644
--- a/third_party/blink/web_tests/platform/win/media/track/track-cue-rendering-vertical-expected.png
+++ b/third_party/blink/web_tests/platform/win/media/track/track-cue-rendering-vertical-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/media/track/track-cue-rendering-vertical-expected.png b/third_party/blink/web_tests/platform/win7/media/track/track-cue-rendering-vertical-expected.png
index 950738b..12d70d3 100644
--- a/third_party/blink/web_tests/platform/win7/media/track/track-cue-rendering-vertical-expected.png
+++ b/third_party/blink/web_tests/platform/win7/media/track/track-cue-rendering-vertical-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win7/virtual/video-surface-layer/media/track/track-cue-rendering-vertical-expected.png b/third_party/blink/web_tests/platform/win7/virtual/video-surface-layer/media/track/track-cue-rendering-vertical-expected.png
index 950738b..12d70d3 100644
--- a/third_party/blink/web_tests/platform/win7/virtual/video-surface-layer/media/track/track-cue-rendering-vertical-expected.png
+++ b/third_party/blink/web_tests/platform/win7/virtual/video-surface-layer/media/track/track-cue-rendering-vertical-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/display-lock/README.md b/third_party/blink/web_tests/virtual/display-lock/README.md
new file mode 100644
index 0000000..78e12d8b
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/display-lock/README.md
@@ -0,0 +1 @@
+Display locking virtual test suite.
diff --git a/third_party/blink/web_tests/virtual/display-lock/inspector-protocol/css/README.txt b/third_party/blink/web_tests/virtual/display-lock/inspector-protocol/css/README.txt
new file mode 100644
index 0000000..41d2a8fc
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/display-lock/inspector-protocol/css/README.txt
@@ -0,0 +1 @@
+CSS Inspector virtual suite to be run with DisplayLocking enabled.
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
index 27a428fd..550775a 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -947,6 +947,7 @@
 [Worker]     method mark
 [Worker]     method measure
 [Worker]     method now
+[Worker]     method profile
 [Worker]     method setElementTimingBufferMaxSize
 [Worker]     method setEventTimingBufferMaxSize
 [Worker]     method setResourceTimingBufferSize
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
index 6e50647..e5a831b 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -5361,6 +5361,7 @@
     method mark
     method measure
     method now
+    method profile
     method setElementTimingBufferMaxSize
     method setEventTimingBufferMaxSize
     method setResourceTimingBufferSize
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt
index b5f59d7..43d13e5 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -929,6 +929,7 @@
 [Worker]     method mark
 [Worker]     method measure
 [Worker]     method now
+[Worker]     method profile
 [Worker]     method setElementTimingBufferMaxSize
 [Worker]     method setEventTimingBufferMaxSize
 [Worker]     method setResourceTimingBufferSize
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/intersection-observer.html b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/intersection-observer.html
new file mode 100644
index 0000000..1787f6f
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/display-lock/lock-after-append/intersection-observer.html
@@ -0,0 +1,180 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>Display Locking: intersection observer interactions</title>
+<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+div {
+  contain: style layout;
+  width: 100px;
+  height: 100px;
+}
+#spacer {
+  height: 3000px;
+}
+</style>
+
+<div id="target1">
+  <div id="target2"></div>
+</div>
+<div id="target3">
+  <div id="target4"></div>
+</div>
+<div id="spacer"></div>
+<div id="find_me"></div>
+
+<script>
+async_test((t) => {
+  let target1, target2, target3, target4;
+  let observer;
+  let entries = [];
+
+  // Set everything up.
+  function enqueueStep1() {
+    target1 = document.getElementById("target1");
+    target2 = document.getElementById("target2");
+    target3 = document.getElementById("target3");
+    target4 = document.getElementById("target4");
+
+    observer = new IntersectionObserver((new_entries) => {
+      entries = entries.concat(new_entries);
+    });
+    observer.observe(target1);
+    observer.observe(target2);
+    observer.observe(target3);
+    observer.observe(target4);
+
+    entries = entries.concat(observer.takeRecords());
+    t.step(() => { assert_equals(entries.length, 0, "No initial notifications") });
+    requestAnimationFrame(() => {
+      requestAnimationFrame(() => {
+        runStep1();
+      });
+    });
+  }
+
+  // Verify that all elements are visible at the start, with intersection events.
+  function runStep1() {
+    const step = arguments.callee.name;
+    t.step(() => {
+      assert_equals(entries.length, 4, step);
+      // Clear the observed visible targets.
+      for (let i = 0; i < entries.length; ++i) {
+        assert_true(entries[i].isIntersecting);
+        assert_true(entries[i].target === target1 ||
+                    entries[i].target === target2 ||
+                    entries[i].target === target3 ||
+                    entries[i].target === target4, step);
+      }
+    });
+
+    entries = [];
+    enqueueStep2();
+  }
+
+  // Lock target3.
+  async function enqueueStep2() {
+    await target3.displayLock.acquire({ timeout: Infinity });
+    requestAnimationFrame(() => {
+      requestAnimationFrame(() => {
+        runStep2();
+      });
+    });
+  }
+
+  // Verify that the locked element received a not-intersecting event.
+  function runStep2() {
+    const step = arguments.callee.name;
+    t.step(() => {
+      assert_equals(entries.length, 1, step);
+      assert_false(entries[0].isIntersecting, step);
+      assert_equals(entries[0].target, target4, step);
+    });
+
+    entries = [];
+    enqueueStep3();
+  }
+
+  // Scroll all elements off screen.
+  function enqueueStep3() {
+    document.getElementById("find_me").scrollIntoView();
+    requestAnimationFrame(() => {
+      requestAnimationFrame(() => {
+        runStep3();
+      });
+    });
+  }
+
+  // Verify that all elements received not intersecting event, except
+  // target4, which was already not intersecting due to being locked.
+  function runStep3() {
+    const step = arguments.callee.name;
+    t.step(() => {
+      assert_equals(entries.length, 3, step);
+      for (let i = 0; i < entries.length; ++i) {
+        assert_false(entries[i].isIntersecting, step);
+        assert_not_equals(entries[i].target, target4, step);
+      }
+    });
+
+    entries = [];
+    enqueueStep4();
+  }
+
+  // Scroll the elements back on screen.
+  function enqueueStep4() {
+    target1.scrollIntoView();
+    requestAnimationFrame(() => {
+      requestAnimationFrame(() => {
+        runStep4();
+      });
+    });
+  }
+
+  // Verify that all elements received not intersecting event, except
+  // target4, which remains not intersecting.
+  function runStep4() {
+    const step = arguments.callee.name;
+    t.step(() => {
+      assert_equals(entries.length, 3, step);
+      for (let i = 0; i < entries.length; ++i) {
+        assert_true(entries[i].isIntersecting);
+        assert_not_equals(entries[i].target, target4, step);
+      }
+    });
+
+    entries = [];
+    enqueueStep5();
+  }
+
+  // Unlock target3.
+  async function enqueueStep5() {
+    await target3.displayLock.commit();
+    requestAnimationFrame(() => {
+      requestAnimationFrame(() => {
+        runStep5();
+      });
+    });
+  }
+
+  function runStep5() {
+    const step = arguments.callee.name;
+    t.step(() => {
+      assert_equals(entries.length, 1, step);
+      assert_true(entries[0].isIntersecting, step);
+      assert_equals(entries[0].target, target4, step);
+    });
+    t.done();
+  }
+
+
+  window.onload = () => {
+    requestAnimationFrame(enqueueStep1);
+  };
+}, "IntersectionObserver interactions");
+</script>
diff --git a/third_party/blink/web_tests/xr/events_input_sources_change.html b/third_party/blink/web_tests/xr/events_input_sources_change.html
index 52eca34d..a4b01318 100644
--- a/third_party/blink/web_tests/xr/events_input_sources_change.html
+++ b/third_party/blink/web_tests/xr/events_input_sources_change.html
@@ -46,7 +46,7 @@
       if (inputChangeEvents === 1) {
         validateAdded(event.added, 1);
         validateRemoved(event.removed, 0);
-        cached_input_source = Array.from(session.inputSources.values())[0];
+        cached_input_source = session.inputSources[0];
         assert_not_equals(cached_input_source, null);
       } else if (inputChangeEvents === 2) {
         // The second event should be removing our controller.
@@ -112,8 +112,4 @@
 
 xr_session_promise_test(
   testFunction, fakeDeviceInitParams, requestSessionModes, testName);
-
-
-
-
 </script>
diff --git a/third_party/blink/web_tests/xr/resources/xr-internal-device-mocking.js b/third_party/blink/web_tests/xr/resources/xr-internal-device-mocking.js
index 77f8213..2079b0d 100644
--- a/third_party/blink/web_tests/xr/resources/xr-internal-device-mocking.js
+++ b/third_party/blink/web_tests/xr/resources/xr-internal-device-mocking.js
@@ -120,6 +120,7 @@
     this.primary_input_pressed_ = false;
     this.primary_input_clicked_ = false;
     this.grip_ = null;
+    this.gamepad_ = null;
 
     this.target_ray_mode_ = 'gaze';
     this.pointer_offset_ = null;
@@ -205,6 +206,28 @@
     }
   }
 
+  get gamepad() {
+    return this.gamepad_;
+  }
+
+  connectGamepad() {
+    // Mojo complains if some of the properties on Gamepad are null, so set
+    // everything to reasonable defaults that tests can override.
+    this.gamepad_ = new device.mojom.Gamepad();
+    this.gamepad_.connected = true;
+    this.gamepad_.id = "unknown";
+    this.gamepad_.timestamp = 0;
+    this.gamepad_.axes = [];
+    this.gamepad_.buttons = [];
+    this.gamepad_.mapping = "";
+    this.gamepad_.display_id = 0;
+    this.gamepad_.hand = device.mojom.GamepadHand.GamepadHandNone;
+  }
+
+  disconnectGamepad() {
+    this.gamepad_ = null;
+  }
+
   getInputSourceState() {
     let input_state = new device.mojom.XRInputSourceState();
 
@@ -215,6 +238,8 @@
 
     input_state.grip = this.grip_;
 
+    input_state.gamepad = this.gamepad_;
+
     if (this.desc_dirty_) {
       let input_desc = new device.mojom.XRInputSourceDescription();
 
diff --git a/third_party/blink/web_tests/xr/xrInputSource_gamepad_disconnect.html b/third_party/blink/web_tests/xr/xrInputSource_gamepad_disconnect.html
new file mode 100644
index 0000000..f0f33745
--- /dev/null
+++ b/third_party/blink/web_tests/xr/xrInputSource_gamepad_disconnect.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<script src="file:///gen/layout_test_data/mojo/public/js/mojo_bindings.js"></script>
+<script src="file:///gen/device/vr/public/mojom/vr_service.mojom.js"></script>
+<script src="../external/wpt/resources/chromium/webxr-test.js"></script>
+<script src="../external/wpt/webxr/resources/webxr_test_constants.js"></script>
+<script src="../xr/resources/xr-internal-device-mocking.js"></script>
+<script src="../xr/resources/xr-test-utils.js"></script>
+<canvas id="webgl-canvas"></canvas>
+
+<script>
+let testName = "WebXR InputSource's gamepad gets disconnected when the input source is removed";
+
+let watcherDone = new Event("watcherdone");
+
+let fakeDeviceInitParams = { supportsImmersive:true };
+
+let requestSessionModes = ['immersive-vr'];
+
+let testFunction = function(session, t, fakeDeviceController) {
+  let eventWatcher = new EventWatcher(t, session, ["watcherdone"]);
+  let eventPromise = eventWatcher.wait_for(["watcherdone"]);
+
+  // Need to have a valid pose or input events don't process.
+  fakeDeviceController.setXRPresentationFrameData(VALID_POSE_MATRIX, [{
+      eye:"left",
+      projectionMatrix: VALID_PROJECTION_MATRIX,
+      viewMatrix: VALID_VIEW_MATRIX
+    }, {
+      eye:"right",
+      projectionMatrix: VALID_PROJECTION_MATRIX,
+      viewMatrix: VALID_VIEW_MATRIX
+    }]);
+
+  let inputChangeEvents = 0;
+  let cached_input_source = null;
+  function onInputSourcesChange(event) {
+    t.step(() => {
+      inputChangeEvents++;
+
+      // The first change event should be adding our controller/gamepad.
+      if (inputChangeEvents === 1) {
+        // We should have one input source
+        assert_equals(session.inputSources.length, 1,
+          "should initially have an input source");
+        assertGamepadConnected();
+      } else if (inputChangeEvents === 2) {
+        // The second event should be disconnecting our gamepad, we should still
+        // have an input source.
+        assert_equals(session.inputSources.length, 1,
+          "removing the gamepad shouldn't remove the input source");
+        assertGamepadDisconnected();
+      } else if (inputChangeEvents === 3) {
+        assert_equals(session.inputSources.length, 1,
+          "re-adding the gamepad shouldn't add an extra input source");
+        // The third event should be reconnecting our gamepad, we should still
+        // have an input source.
+        assertGamepadConnected();
+      } else if (inputChangeEvents === 4) {
+        // The fourth event should be disconnecting our gamepad, we should no
+        // longer have an input source.
+        assert_equals(session.inputSources.length, 0,
+          "input source should have been disconnected");
+        assertGamepadDisconnected();
+      } else if (inputChangeEvents === 5) {
+        // The fifth event should be re-connecting our gamepad to prep for
+        // ending the session.
+        assert_equals(session.inputSources.length, 1,
+        "input source should have been re-connected");
+        assertGamepadConnected();
+        session.dispatchEvent(watcherDone);
+      }
+    });
+  }
+
+  function assertGamepadConnected() {
+    cached_input_source = session.inputSources[0];
+    assert_not_equals(cached_input_source, null,
+      "Expect to get a cached_input_source, iteration: " + inputChangeEvents);
+    assert_not_equals(cached_input_source.gamepad, null,
+      "Expect to have a gamepad, iteration: " + inputChangeEvents);
+    assert_true(cached_input_source.gamepad.connected,
+      "Expect the gamepad to be connected, iteration: " + inputChangeEvents);
+  }
+
+  function assertGamepadDisconnected() {
+    assert_not_equals(cached_input_source, null,
+      "Expect to have a cached_input_source, iteration: " + inputChangeEvents);
+    assert_not_equals(cached_input_source.gamepad, null,
+      "Expect to have a gamepad on cached_input_source, iteration: " + inputChangeEvents);
+    assert_false(cached_input_source.gamepad.connected,
+      "Expect cached gamepad to be disconnected, iteration: " + inputChangeEvents);
+  }
+
+  session.addEventListener('inputsourceschange', onInputSourcesChange, false);
+
+  // Session must have a baseLayer or frame requests will be ignored.
+  session.updateRenderState({ baseLayer: new XRWebGLLayer(session, gl) });
+
+  // Create our input source and immediately toggle the primary input so that
+  // it appears as already needing to send a click event when it appears.
+  let input_source = new MockXRInputSource();
+  input_source.connectGamepad();
+  fakeDeviceController.addInputSource(input_source);
+
+  // Input events need one frame to propagate, so this does (in order and running
+  // a rAF after each step:
+  // 1. Disconnect the gamepad (so we can verify that the gamepad is disconnected)
+  // 2. Reconnect the gamepad (so we can set up to disconnect the controller)
+  // 3. Disconnect the controller (so we can verify that it's gamepad gets disconnected).
+  // 4. Adds the controller back (so we can test the end Session)
+  // 5. Waits for all of the input events to finish propagating, then ends the
+  // session, at which point the controller should be disconnected.
+  return new Promise((resolve) => {
+    session.requestAnimationFrame(() => {
+      input_source.disconnectGamepad();
+      session.requestAnimationFrame(() => {
+        input_source.connectGamepad();
+        session.requestAnimationFrame(() => {
+          fakeDeviceController.removeInputSource(input_source);
+          session.requestAnimationFrame(() => {
+            fakeDeviceController.addInputSource(input_source);
+            session.requestAnimationFrame(() => {
+              eventPromise.then(() => {
+                session.end().then(() => {
+                  assertGamepadDisconnected();
+                  resolve();
+                });
+              });
+            });
+          });
+        });
+      });
+    });
+  });
+};
+
+xr_session_promise_test(
+  testFunction, fakeDeviceInitParams, requestSessionModes, testName);
+</script>
diff --git a/third_party/crashpad/README.chromium b/third_party/crashpad/README.chromium
index 197512d..4865a99 100644
--- a/third_party/crashpad/README.chromium
+++ b/third_party/crashpad/README.chromium
@@ -2,7 +2,7 @@
 Short Name: crashpad
 URL: https://crashpad.chromium.org/
 Version: unknown
-Revision: daf9f5669eedec1c326dd07f623872c1c4cc01a5
+Revision: ee1d5124a2bfec578a1474b048cf934d92dcf7ba
 License: Apache 2.0
 License File: crashpad/LICENSE
 Security Critical: yes
diff --git a/third_party/crashpad/crashpad/snapshot/elf/elf_image_reader.cc b/third_party/crashpad/crashpad/snapshot/elf/elf_image_reader.cc
index 7c03a36..7f6d7c7e 100644
--- a/third_party/crashpad/crashpad/snapshot/elf/elf_image_reader.cc
+++ b/third_party/crashpad/crashpad/snapshot/elf/elf_image_reader.cc
@@ -22,6 +22,7 @@
 #include <vector>
 
 #include "base/logging.h"
+#include "base/numerics/safe_math.h"
 #include "build/build_config.h"
 #include "util/numeric/checked_vm_address_range.h"
 
@@ -277,10 +278,24 @@
   current_address_ += sizeof(note_info);
 
   constexpr size_t align = sizeof(note_info.n_namesz);
-#define PAD(x) (((x) + align - 1) & ~(align - 1))
-  size_t padded_namesz = PAD(note_info.n_namesz);
-  size_t padded_descsz = PAD(note_info.n_descsz);
-  size_t note_size = padded_namesz + padded_descsz;
+
+#define CHECKED_PAD(x, into)                                 \
+  base::CheckAnd(base::CheckAdd(x, align - 1), ~(align - 1)) \
+      .AssignIfValid(&into)
+
+  size_t padded_namesz;
+  if (!CHECKED_PAD(note_info.n_namesz, padded_namesz)) {
+    return Result::kError;
+  }
+  size_t padded_descsz;
+  if (!CHECKED_PAD(note_info.n_descsz, padded_descsz)) {
+    return Result::kError;
+  }
+
+  size_t note_size;
+  if (!base::CheckAdd(padded_namesz, padded_descsz).AssignIfValid(&note_size)) {
+    return Result::kError;
+  }
 
   // Notes typically have 4-byte alignment. However, .note.android.ident may
   // inadvertently use 2-byte alignment.
@@ -289,9 +304,19 @@
   // but there may be 4-byte aligned notes following it. If this note was
   // aligned at less than 4-bytes, expect that the next note will be aligned at
   // 4-bytes and add extra padding, if necessary.
-  VMAddress end_of_note =
-      std::min(PAD(current_address_ + note_size), segment_end_address_);
-#undef PAD
+
+  VMAddress end_of_note_candidate;
+  if (!base::CheckAdd(current_address_, note_size)
+           .AssignIfValid(&end_of_note_candidate)) {
+    return Result::kError;
+  }
+  VMAddress end_of_note;
+  if (!CHECKED_PAD(end_of_note_candidate, end_of_note)) {
+    return Result::kError;
+  }
+  end_of_note = std::min(end_of_note, segment_end_address_);
+
+#undef CHECKED_PAD
 
   if (note_size > max_note_size_) {
     current_address_ = end_of_note;
diff --git a/third_party/webxr_test_pages/webxr-samples/input-selection.html b/third_party/webxr_test_pages/webxr-samples/input-selection.html
index 8a6402b..6a7801a 100644
--- a/third_party/webxr_test_pages/webxr-samples/input-selection.html
+++ b/third_party/webxr_test_pages/webxr-samples/input-selection.html
@@ -432,6 +432,7 @@
           // Save the session-specific reference space, and apply the
           // current player orientation/position as originOffset.
           setRefSpace(session, refSpace, false);
+          updateOriginOffset(session);
           session.requestReferenceSpace('viewer').then(function(viewerSpace){
             xrViewerSpace = viewerSpace;
             session.requestAnimationFrame(onXRFrame);
diff --git a/tools/check_grd_for_unused_strings.py b/tools/check_grd_for_unused_strings.py
index 71ba386..1c6497a 100755
--- a/tools/check_grd_for_unused_strings.py
+++ b/tools/check_grd_for_unused_strings.py
@@ -132,6 +132,7 @@
     chrome_app_dir = os.path.join(chrome_dir, 'app')
     chrome_app_res_dir = os.path.join(chrome_app_dir, 'resources')
     device_base_dir = os.path.join(src_dir, 'device')
+    services_dir = os.path.join(src_dir, 'services')
     ui_dir = os.path.join(src_dir, 'ui')
     ui_strings_dir = os.path.join(ui_dir, 'strings')
     ui_chromeos_dir = os.path.join(ui_dir, 'chromeos')
@@ -156,6 +157,7 @@
                    'renderer_resources.grd'),
       os.path.join(device_base_dir, 'bluetooth', 'bluetooth_strings.grd'),
       os.path.join(device_base_dir, 'fido', 'fido_strings.grd'),
+      os.path.join(services_dir, 'services_strings.grd')
       os.path.join(src_dir, 'chromeos', 'chromeos_strings.grd'),
       os.path.join(src_dir, 'extensions', 'strings', 'extensions_strings.grd'),
       os.path.join(src_dir, 'ui', 'resources', 'ui_resources.grd'),
diff --git a/tools/chrome_proxy/webdriver/lite_page.py b/tools/chrome_proxy/webdriver/lite_page.py
index 85fbeefd..d0f8aa5 100644
--- a/tools/chrome_proxy/webdriver/lite_page.py
+++ b/tools/chrome_proxy/webdriver/lite_page.py
@@ -115,8 +115,11 @@
       self.assertGreater(1, image_responses)
 
   # Tests that the stale previews UI is shown on a stale Lite page.
+  # The stale timestamp histogram is not logged with the new UI unless the page
+  # info dialog is opened which can't be done in a ChromeDriver test.
   @AndroidOnly
   @ChromeVersionEqualOrAfterM(65)
+  @ChromeVersionBeforeM(76)
   def testStaleLitePageNano(self):
     # If it was attempted to run with another experiment, skip this test.
     if common.ParseFlags().browser_args and ('--data-reduction-proxy-experiment'
diff --git a/tools/gritsettings/resource_ids b/tools/gritsettings/resource_ids
index 8f879aae..2a7cb2d 100644
--- a/tools/gritsettings/resource_ids
+++ b/tools/gritsettings/resource_ids
@@ -388,6 +388,10 @@
     "messages": [24900],
   },
 
+  "services/services_strings.grd": {
+    "messages": [25300],
+  },
+
   "third_party/blink/public/blink_image_resources.grd": {
     "structures": [25400],
   },
diff --git a/tools/gritsettings/translation_expectations.pyl b/tools/gritsettings/translation_expectations.pyl
index 2b955b17..83c03e53 100644
--- a/tools/gritsettings/translation_expectations.pyl
+++ b/tools/gritsettings/translation_expectations.pyl
@@ -61,6 +61,7 @@
       "ios/chrome/search_widget_extension/strings/ios_search_widget_extension_google_chrome_strings.grd",
       "ios/chrome/share_extension/strings/ios_share_extension_strings.grd",
       "remoting/resources/remoting_strings.grd",
+      "services/services_strings.grd",
       "third_party/libaddressinput/chromium/address_input_strings.grd",
       "ui/accessibility/extensions/strings/accessibility_extensions_strings.grd",
       "ui/android/java/strings/android_ui_strings.grd",
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 1ca694f..52ea8f22 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -101,7 +101,6 @@
       'chromeos-amd64-generic-cfi-thin-lto-rel': 'cros_chrome_sdk_headless_ozone_cfi_thin_lto',
       'chromeos-amd64-generic-rel': 'cros_chrome_sdk_headless_ozone',
       'chromeos-arm-generic-rel': 'cros_chrome_sdk',
-      'chromeos-daisy-rel': 'cros_chrome_sdk',
       'chromeos-kevin-rel': 'cros_chrome_sdk_headless_ozone',
       'linux-chromeos-rel': 'chromeos_with_codecs_release_bot',
       'linux-chromeos-dbg': 'chromeos_with_codecs_debug_bot',
@@ -228,12 +227,12 @@
       'Mac Builder (dbg) Goma Canary': 'debug_bot',
       'Mac Builder (dbg) Goma Latest Client (clobber)': 'debug_bot',
       'Mac Builder (dbg) Goma Latest Client': 'debug_bot',
-      'Mac Builder Goma Canary': 'gpu_tests_release_bot',
-      'Mac Builder Goma Latest Client': 'gpu_tests_release_bot',
-      'Mac Goma Canary (clobber)': 'release_bot_mac_strip',
-      'Mac Goma Canary LocalOutputCache': 'release_bot_mac_strip',
-      'Mac Goma Latest Client (clobber)': 'release_bot_mac_strip',
-      'Mac Goma Latest Client LocalOutputCache': 'release_bot_mac_strip',
+      'Mac Builder Goma Canary': 'gpu_tests_release_bot_minimal_symbols',
+      'Mac Builder Goma Latest Client': 'gpu_tests_release_bot_minimal_symbols',
+      'Mac Goma Canary (clobber)': 'release_bot_mac_strip_minimal_symbols',
+      'Mac Goma Canary LocalOutputCache': 'release_bot_mac_strip_minimal_symbols',
+      'Mac Goma Latest Client (clobber)': 'release_bot_mac_strip_minimal_symbols',
+      'Mac Goma Latest Client LocalOutputCache': 'release_bot_mac_strip_minimal_symbols',
 
       'Win7 Builder (dbg) Goma Canary': 'debug_trybot_x86',
       'Win7 Builder (dbg) Goma Latest Client': 'debug_trybot_x86',
@@ -259,9 +258,9 @@
 
       'ios-simulator-code-coverage': 'clang_code_coverage_ios',
       'ios-simulator': 'ios_error',
-      'Jumbo Linux x64': 'jumbo_large_chunks_release_bot_minimal_symbols',
-      'Jumbo Mac': 'jumbo_release_bot_minimal_symbols',
-      'Jumbo Win x64': 'jumbo_release_bot_minimal_symbols',
+      'Jumbo Linux x64': 'jumbo_large_chunks_release_bot_compile_only',
+      'Jumbo Mac': 'jumbo_release_bot_compile_only',
+      'Jumbo Win x64': 'jumbo_release_bot_compile_only',
       'Libfuzzer Upload Chrome OS ASan': 'libfuzzer_chromeos_asan_release_bot',
       'Libfuzzer Upload Linux ASan': 'libfuzzer_asan_release_bot',
       'Libfuzzer Upload Linux ASan Debug': 'libfuzzer_asan_debug_bot',
@@ -280,7 +279,7 @@
       'linux-blink-heap-verification': 'release_bot_enable_blink_heap_verification_dcheck_always_on',
       'linux-chromium-tests-staging-builder': 'release_bot',
       'linux-code-coverage': 'clang_code_coverage',
-      'Mac deterministic': 'release_bot_mac_strip',
+      'Mac deterministic': 'release_bot_mac_strip_minimal_symbols',
       'Mac deterministic (dbg)': 'debug_bot',
       'mac-autofill-captured-sites-rel': 'release_bot',
 
@@ -352,7 +351,7 @@
       'GPU Mac Builder (dbg)': 'gpu_tests_debug_trybot',
       'GPU Linux Builder': 'gpu_tests_release_trybot',
       'GPU Linux Builder (dbg)': 'gpu_tests_debug_trybot',
-      'GPU Win Builder': 'gpu_tests_release_trybot_x86_minimal_symbols_resource_whitelisting',
+      'GPU Win Builder': 'gpu_tests_release_trybot_x86_resource_whitelisting',
       'GPU Win Builder (dbg)': 'gpu_tests_debug_trybot_x86',
       'Android Release (Nexus 5X)': 'gpu_tests_android_release_trybot_arm64',
     },
@@ -409,7 +408,7 @@
         'local': 'debug_bot_local_build',
         'goma': 'debug_bot',
       },
-      'Deterministic Linux': 'release_bot',
+      'Deterministic Linux': 'release_bot_minimal_symbols',
       'Fuchsia ARM64': 'release_bot_fuchsia_arm64',
       'Fuchsia x64': 'release_bot_fuchsia',
       'Leak Detection Linux': 'release_bot',
@@ -448,7 +447,7 @@
     'chromium.mac': {
       'Mac Builder': 'gpu_tests_release_bot_minimal_symbols',
       'Mac Builder (dbg)': 'gpu_tests_debug_bot',
-      'mac-jumbo-rel': 'jumbo_large_chunks_release_bot_minimal_symbols',
+      'mac-jumbo-rel': 'jumbo_large_chunks_release_bot_compile_only',
       'ios-device': 'ios_error',
       'ios-device-xcode-clang': 'ios_error',
       'ios-simulator': 'ios_error',
@@ -533,7 +532,7 @@
       'V8-Blink Linux 64 (dbg)': 'release_bot_v8_debug',
       'V8-Blink Mac': 'release_bot',
       'V8-Blink Win': 'release_bot_x86_minimal_symbols',
-      'Win V8 FYI Release (NVIDIA)': 'gpu_tests_release_trybot_x86_minimal_symbols_resource_whitelisting',
+      'Win V8 FYI Release (NVIDIA)': 'gpu_tests_release_trybot_x86_resource_whitelisting',
     },
 
     # TODO(crbug.com/818301): This master is going away.
@@ -569,7 +568,7 @@
       # Windows bots take too long to link w/ full symbols and time out.
       'Win Builder': 'gpu_tests_release_bot_x86_minimal_symbols',
       'Win Builder (dbg)': 'gpu_tests_debug_bot_x86',
-      'win-jumbo-rel': 'jumbo_large_chunks_release_bot_minimal_symbols',
+      'win-jumbo-rel': 'jumbo_large_chunks_release_bot_compile_only',
       'Win x64 Builder': 'gpu_tests_release_bot_minimal_symbols',
       'Win x64 Builder (dbg)': 'gpu_tests_debug_bot',
       'Windows deterministic': 'release_bot_x86_minimal_symbols',
@@ -610,7 +609,7 @@
       # shared library loading is fixed.
       'android-cronet-arm-dbg': 'android_cronet_debug_static_bot_arm_no_neon',
       'android-kitkat-arm-rel': 'android_release_trybot',
-      'android-marshmallow-arm64-rel': 'gpu_tests_android_release_trybot_arm64_minimal_symbols',
+      'android-marshmallow-arm64-rel': 'gpu_tests_android_release_trybot_arm64_resource_whitelisting',
       'android-oreo-arm64-cts-networkservice-dbg': 'android_debug_trybot_arm64',
       'android_archive_rel_ng': 'android_release_trybot',
       'android_arm64_dbg_recipe': 'android_debug_trybot_compile_only_arm64',
@@ -631,7 +630,7 @@
       'android_optional_gpu_tests_rel': 'gpu_tests_android_release_trybot_arm64',
       'android_unswarmed_pixel_aosp': 'android_debug_trybot_arm64',
       'android-deterministic-dbg': 'android_debug_trybot',
-      'android-deterministic-rel': 'android_without_codecs_release_trybot_minimal_symbols',
+      'android-deterministic-rel': 'android_without_codecs_release_trybot',
       'cast_shell_android': 'android_cast_debug_static_bot_compile_only',
       'gpu-fyi-try-android-l-nexus-5-32': 'gpu_tests_android_release_trybot',
       'gpu-fyi-try-android-l-nexus-6-32': 'gpu_tests_android_release_trybot',
@@ -677,7 +676,6 @@
       'chromeos-amd64-generic-cfi-thin-lto-rel': 'cros_chrome_sdk_headless_ozone_cfi_thin_lto',
       'chromeos-amd64-generic-rel': 'cros_chrome_sdk_headless_ozone',
       'chromeos-arm-generic-rel': 'cros_chrome_sdk_dchecks_always_on',
-      'chromeos-daisy-rel': 'cros_chrome_sdk_dchecks_always_on',
       'chromeos-kevin-compile-rel': 'cros_chrome_sdk_headless_ozone',
       'chromeos-kevin-rel': 'cros_chrome_sdk_headless_ozone',
       'linux-chromeos-rel': 'chromeos_with_codecs_release_trybot',
@@ -724,7 +722,7 @@
       'linux-dcheck-off-rel': 'release_trybot_dcheck_off',
       'linux-goma-rbe-staging-rel': 'gpu_tests_release_trybot_no_symbols',
       'linux-gcc-rel': 'release_bot_x86_minimal_symbols_no_clang_cxx11',
-      'linux-jumbo-rel': 'jumbo_large_chunks_release_bot_minimal_symbols',
+      'linux-jumbo-rel': 'jumbo_large_chunks_release_bot_compile_only',
       'linux-libfuzzer-asan-rel': 'libfuzzer_asan_release_trybot',
       'linux-ozone-rel': 'ozone_linux_release_trybot',
       'linux-rel': 'gpu_tests_release_trybot_no_symbols_use_dummy_lastchange',
@@ -785,11 +783,11 @@
       'ios-simulator-full-configs': 'ios_error',
       'ios-simulator-cronet': 'ios_error',
       'ios-simulator-xcode-clang': 'ios_error',
-      'mac-jumbo-rel': 'jumbo_large_chunks_release_bot_minimal_symbols',
+      'mac-jumbo-rel': 'jumbo_large_chunks_release_bot_compile_only',
       'mac_chromium_10.10': 'gpu_tests_release_trybot',
       'mac_chromium_10.12_rel_ng': 'gpu_tests_release_trybot',
       'mac_chromium_10.13_rel_ng': 'release_trybot',
-      'mac_chromium_archive_rel_ng': 'release_bot_mac_strip',
+      'mac_chromium_archive_rel_ng': 'release_bot_mac_strip_minimal_symbols',
       'mac_chromium_asan_rel_ng': 'asan_dcheck_disable_nacl_release_bot',
       'mac_chromium_compile_dbg_ng': 'gpu_tests_debug_trybot',
       'mac_chromium_compile_rel_ng': 'gpu_tests_release_trybot',
@@ -823,21 +821,21 @@
       'gpu-fyi-try-win10-nvidia-exp': 'gpu_fyi_tests_release_trybot_x86',
       'gpu-fyi-try-win10-nvidia-rel': 'gpu_fyi_tests_release_trybot_x86',
       'gpu-try-win10-nvidia-dbg': 'gpu_tests_debug_trybot_x86',
-      'win7_chromium_rel_loc_exp': 'gpu_tests_release_trybot_x86_minimal_symbols_resource_whitelisting',
+      'win7_chromium_rel_loc_exp': 'gpu_tests_release_trybot_x86_resource_whitelisting',
       'win10_chromium_x64_dbg_ng': 'gpu_tests_debug_trybot',
       'win10_chromium_x64_rel_ng': 'gpu_tests_release_trybot_resource_whitelisting',
       'win10_chromium_x64_rel_ng_exp': 'release_trybot',
       'win-annotator-rel': 'release_trybot',
       'win-asan': 'asan_clang_fuzzer_static_v8_heap_minimal_symbols_release',
-      'win-jumbo-rel': 'jumbo_large_chunks_release_bot_minimal_symbols',
+      'win-jumbo-rel': 'jumbo_large_chunks_release_bot_compile_only',
       'win-libfuzzer-asan-rel': 'libfuzzer_windows_asan_release_trybot',
-      'win7-rel': 'gpu_tests_release_trybot_x86_minimal_symbols_resource_whitelisting',
+      'win7-rel': 'gpu_tests_release_trybot_x86_resource_whitelisting',
       'win_x64_archive': 'release_trybot',
       'win_archive': 'release_trybot_x86',
       'win_chromium_compile_dbg_ng': 'gpu_tests_debug_trybot_x86',
-      'win_chromium_compile_rel_ng': 'gpu_tests_release_trybot_x86_minimal_symbols_resource_whitelisting',
+      'win_chromium_compile_rel_ng': 'gpu_tests_release_trybot_x86_resource_whitelisting',
       'win_chromium_dbg_ng': 'gpu_tests_debug_trybot_x86',
-      'win_chromium_x64_rel_ng': 'gpu_tests_release_trybot_minimal_symbols',
+      'win_chromium_x64_rel_ng': 'gpu_tests_release_trybot',
       'win_mojo': 'release_trybot_x86',
       'win_optional_gpu_tests_rel': 'gpu_fyi_tests_release_trybot_x86',
       'win_upload_clang': 'release_bot',
@@ -853,7 +851,7 @@
     },
 
     'tryserver.webrtc': {
-      'win_chromium_compile': 'gpu_tests_release_trybot_x86_minimal_symbols_resource_whitelisting',
+      'win_chromium_compile': 'gpu_tests_release_trybot_x86_resource_whitelisting',
       'mac_chromium_compile': 'gpu_tests_release_trybot',
       'linux_chromium_compile': 'release_trybot',
       'android_chromium_compile': 'android_release_trybot',
@@ -1092,8 +1090,8 @@
       'android_without_codecs', 'release_bot', 'minimal_symbols', 'strip_debug_info',
     ],
 
-    'android_without_codecs_release_trybot_minimal_symbols': [
-      'android_without_codecs', 'release_trybot', 'minimal_symbols', 'strip_debug_info',
+    'android_without_codecs_release_trybot': [
+      'android_without_codecs', 'release_trybot', 'strip_debug_info',
     ],
 
     'asan_clang_shared_v8_heap_minimal_symbols_release_tot': [
@@ -1467,11 +1465,11 @@
     ],
 
     'gpu_fyi_tests_release_trybot_asan': [
-      'gpu_fyi_tests', 'release_trybot', 'asan', 'minimal_symbols', 'disable_nacl',
+      'gpu_fyi_tests', 'release_trybot', 'asan', 'disable_nacl',
     ],
 
     'gpu_fyi_tests_release_trybot_tsan': [
-      'gpu_fyi_tests', 'release_trybot', 'tsan', 'minimal_symbols', 'disable_nacl',
+      'gpu_fyi_tests', 'release_trybot', 'tsan', 'disable_nacl',
     ],
 
     'gpu_fyi_tests_release_trybot_x86': [
@@ -1495,9 +1493,8 @@
       'gpu_tests', 'android', 'release_trybot', 'arm64', 'static_angle',
     ],
 
-    'gpu_tests_android_release_trybot_arm64_minimal_symbols': [
-      'android', 'release_trybot', 'arm64', 'minimal_symbols', 'static_angle',
-      'resource_whitelisting',
+    'gpu_tests_android_release_trybot_arm64_resource_whitelisting': [
+      'android', 'release_trybot', 'arm64', 'static_angle', 'resource_whitelisting',
     ],
 
     'gpu_tests_android_vulkan_release_trybot': [
@@ -1562,17 +1559,16 @@
       'use_dummy_lastchange',
     ],
 
-    'gpu_tests_release_trybot_minimal_symbols': [
-      'gpu_tests', 'release_trybot', 'minimal_symbols',
+    'gpu_tests_release_trybot': [
+      'gpu_tests', 'release_trybot',
     ],
 
     'gpu_tests_release_trybot_ptr_comp': [
       'gpu_tests', 'release_trybot', 'v8_pointer_compression',
     ],
 
-    'gpu_tests_release_trybot_x86_minimal_symbols_resource_whitelisting': [
-      'gpu_tests', 'release_trybot', 'x86', 'minimal_symbols',
-      'resource_whitelisting',
+    'gpu_tests_release_trybot_x86_resource_whitelisting': [
+      'gpu_tests', 'release_trybot', 'x86', 'resource_whitelisting',
     ],
 
     'gpu_tests_release_bot': [
@@ -1590,11 +1586,11 @@
     # build files.
     'ios_error': [ 'error'],
 
-    'jumbo_release_bot_minimal_symbols': [
+    'jumbo_release_bot_compile_only': [
       'jumbo', 'release_bot', 'compile_only',
     ],
 
-    'jumbo_large_chunks_release_bot_minimal_symbols': [
+    'jumbo_large_chunks_release_bot_compile_only': [
       'jumbo_non_goma_chunks', 'release_bot', 'compile_only',
     ],
 
@@ -1654,7 +1650,7 @@
     ],
 
     'libfuzzer_windows_asan_release_trybot': [
-      'libfuzzer', 'asan', 'release_trybot', 'chrome_with_codecs', 'pdf_xfa', 'disable_nacl', 'minimal_symbols',
+      'libfuzzer', 'asan', 'release_trybot', 'chrome_with_codecs', 'pdf_xfa', 'disable_nacl',
     ],
 
     'msan_release_bot': [
@@ -1754,10 +1750,6 @@
       'release_bot', 'fuchsia', 'arm64', 'cast', 'no_symbols',
     ],
 
-    'release_bot_mac_strip': [
-      'release_bot', 'mac_strip',
-    ],
-
     'release_bot_mac_strip_minimal_symbols': [
       'release_bot', 'mac_strip', 'minimal_symbols',
     ],
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 1c76bd03..5833ef05 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -44064,6 +44064,14 @@
   <int value="1" label="DocumentLevelTouchPreventDefaultCalled"/>
 </enum>
 
+<enum name="PasswordAddLoginSyncError">
+  <int value="0" label="None"/>
+  <int value="1" label="DB Not Available"/>
+  <int value="2" label="Constraint Violation"/>
+  <int value="3" label="Encryption Service Failure"/>
+  <int value="4" label="DB Error"/>
+</enum>
+
 <enum name="PasswordApplySyncChangesState">
   <int value="0" label="Apply OK"/>
   <int value="1" label="Apply ADD failed"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 92b7fc5..154a5fa 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -45441,6 +45441,28 @@
   </summary>
 </histogram>
 
+<histogram base="true" name="GwpAsan.AllocatorOom.Malloc" units="allocations"
+    expires_after="M80">
+  <owner>vtsyrklevich@chromium.org</owner>
+  <owner>dynamic-tools@google.com</owner>
+  <summary>
+    Reports how many allocations it took for malloc GWP-ASan to OOM. Reported
+    the first time the allocator fails to consecutively allocate
+    GuardedPageAllocator::kOutOfMemoryCount allocations in a row.
+  </summary>
+</histogram>
+
+<histogram base="true" name="GwpAsan.AllocatorOom.PartitionAlloc"
+    units="allocations" expires_after="M80">
+  <owner>vtsyrklevich@chromium.org</owner>
+  <owner>dynamic-tools@google.com</owner>
+  <summary>
+    Reports how many allocations it took for PartitionAlloc GWP-ASan to OOM.
+    Reported the first time the allocator fails to consecutively allocate
+    GuardedPageAllocator::kOutOfMemoryCount allocations in a row.
+  </summary>
+</histogram>
+
 <histogram name="GwpAsan.CrashAnalysisResult" enum="GwpAsanCrashAnalysisResult"
     expires_after="M80">
   <owner>vtsyrklevich@chromium.org</owner>
@@ -89819,13 +89841,24 @@
   </summary>
 </histogram>
 
+<histogram name="PasswordManager.ApplySyncChanges.AddLoginSyncError"
+    enum="PasswordAddLoginSyncError" expires_after="M80">
+  <owner>mamir@chromium.org</owner>
+  <owner>mastiz@chromium.org</owner>
+  <summary>
+    Records different results upon adding a remote password to the password
+    manager. It is recorded every time after receiving remote password
+    incremental updates from the server.
+  </summary>
+</histogram>
+
 <histogram name="PasswordManager.ApplySyncChangesState"
     enum="PasswordApplySyncChangesState" expires_after="M80">
   <owner>mamir@chromium.org</owner>
   <owner>mastiz@chromium.org</owner>
   <summary>
     Records different states upon applying remote sync changes to the password
-    manager. It recorded everytime after receiving remote password incremental
+    manager. It recorded every time after receiving remote password incremental
     updates from the server.
   </summary>
 </histogram>
@@ -90636,6 +90669,17 @@
   </summary>
 </histogram>
 
+<histogram name="PasswordManager.MergeSyncData.AddLoginSyncError"
+    enum="PasswordAddLoginSyncError" expires_after="M80">
+  <owner>mamir@chromium.org</owner>
+  <owner>mastiz@chromium.org</owner>
+  <summary>
+    Records different results upon adding a remote password to the password
+    manager. It is recorded during the initial sync when merging remote and
+    local data.
+  </summary>
+</histogram>
+
 <histogram name="PasswordManager.MultiAccountPasswordUpdateAction"
     enum="MultiAccountUpdateBubbleUserAction" expires_after="2018-03-29">
   <obsolete>
@@ -146110,7 +146154,7 @@
 </histogram>
 
 <histogram name="XHR.Sync.PageDismissal_forbidden" enum="XHRPageDismissalState"
-    expires_after="2019-06-01">
+    expires_after="2019-09-05">
   <owner>kdillon@chromium.org</owner>
   <owner>panicker@chromium.org</owner>
   <summary>
@@ -150772,6 +150816,17 @@
   <affected-histogram name="GwpAsan.CrashAnalysisResult"/>
 </histogram_suffixes>
 
+<histogram_suffixes name="GwpAsanPerProcessOom" separator=".">
+  <suffix name="Browser" label="for the browser process."/>
+  <suffix name="Extension" label="for the extension process."/>
+  <suffix name="Gpu" label="for the gpu-process."/>
+  <suffix name="Ppapi" label="for the ppapi process."/>
+  <suffix name="Renderer" label="for the renderer process."/>
+  <suffix name="Utility" label="for the utility process."/>
+  <affected-histogram name="GwpAsan.AllocatorOom.Malloc"/>
+  <affected-histogram name="GwpAsan.AllocatorOom.PartitionAlloc"/>
+</histogram_suffixes>
+
 <histogram_suffixes name="GWSChromeJointExperiment" separator="_">
   <suffix name="Experiment1"
       label="Only page loads that are a result of a navigation from a web
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml
index 6fb531c..267fd84 100644
--- a/tools/metrics/ukm/ukm.xml
+++ b/tools/metrics/ukm/ukm.xml
@@ -7679,8 +7679,8 @@
       page requested presentation while Chrome was in VR browsing mode. 3:
       HeadsetActivation, the user activated the VR headset while in 2D browsing
       on the page, which listens for headset activations to request
-      presentation. 4: DeepLinkedApp, The page was launched in Chrome from the
-      VR system home (e.g., Daydream Home) and requested presentation.
+      presentation. 4: DeepLinkedApp (Obsolete), The page was launched in Chrome
+      from the VR system home (e.g., Daydream Home) and requested presentation.
     </summary>
   </metric>
 </event>
diff --git a/tools/perf/core/bot_platforms.py b/tools/perf/core/bot_platforms.py
index 4b06a47..1430af5 100644
--- a/tools/perf/core/bot_platforms.py
+++ b/tools/perf/core/bot_platforms.py
@@ -174,14 +174,14 @@
     'Android Nexus6 WebView Perf', 'Android AOSP MOB30K',
     _ANDROID_NEXUS_6_WEBVIEW_BENCHMARK_NAMES,
     num_shards=12)  # Reduced from 16 per crbug.com/891848.
-
-# FYI bots
 ANDROID_PIXEL2 = PerfPlatform(
     'android-pixel2-perf', 'Android OPM1.171019.021',
-    _ANDROID_PIXEL2_BENCHMARK_NAMES, num_shards=7, is_fyi=True)
+    _ANDROID_PIXEL2_BENCHMARK_NAMES, num_shards=35)
 ANDROID_PIXEL2_WEBVIEW = PerfPlatform(
     'android-pixel2_webview-perf', 'Android OPM1.171019.021',
-    _ANDROID_PIXEL2_WEBVIEW_BENCHMARK_NAMES, num_shards=7, is_fyi=True)
+    _ANDROID_PIXEL2_WEBVIEW_BENCHMARK_NAMES, num_shards=28)
+
+# FYI bots
 ANDROID_NEXUS5X_PERF_FYI =  PerfPlatform(
     'android-nexus5x-perf-fyi', 'Android MMB29Q',
     _ANDROID_NEXUS5X_FYI_BENCHMARK_NAMES,
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py
index 7e8533c..1cfaee2 100755
--- a/tools/perf/core/perf_data_generator.py
+++ b/tools/perf/core/perf_data_generator.py
@@ -107,49 +107,6 @@
       'device_os_flavor': 'google',
     },
   },
-  'android-pixel2_webview-perf': {
-    'tests': [
-      {
-        'isolate': 'performance_webview_test_suite',
-        'extra_args': [
-          '--test-shard-map-filename=android-pixel2_webview-perf_map.json',
-        ],
-        'num_shards': 7
-      }
-    ],
-    'platform': 'android-webview-google',
-    'dimension': {
-      'pool': 'chrome.tests.perf-webview-fyi',
-      'os': 'Android',
-      'device_type': 'walleye',
-      'device_os': 'O',
-      'device_os_flavor': 'google',
-    },
-  },
-  'android-pixel2-perf': {
-    'tests': [
-      {
-        'isolate': 'performance_test_suite',
-        'extra_args': [
-          # TODO(crbug.com/612455): Enable ref builds once can pass both
-          # --browser=exact (used by this bot to have it run Monochrome6432)
-          # and --browser=reference together.
-          #'--run-ref-build',
-          '--test-shard-map-filename=android-pixel2-perf_map.json',
-        ],
-        'num_shards': 7
-      }
-    ],
-    'platform': 'android-chrome',
-      'browser': 'bin/monochrome_64_32_bundle',
-    'dimension': {
-      'pool': 'chrome.tests.perf-fyi',
-      'os': 'Android',
-      'device_type': 'walleye',
-      'device_os': 'O',
-      'device_os_flavor': 'google',
-    },
-  },
   'linux-perf-fyi': {
     'tests': [
       {
@@ -432,6 +389,49 @@
       'device_os_flavor': 'aosp',
     },
   },
+  'android-pixel2_webview-perf': {
+    'tests': [
+      {
+        'isolate': 'performance_webview_test_suite',
+        'extra_args': [
+          '--test-shard-map-filename=android-pixel2_webview-perf_map.json',
+        ],
+        'num_shards': 28
+      }
+    ],
+    'platform': 'android-webview-google',
+    'dimension': {
+      'pool': 'chrome.tests.perf-webview',
+      'os': 'Android',
+      'device_type': 'walleye',
+      'device_os': 'O',
+      'device_os_flavor': 'google',
+    },
+  },
+  'android-pixel2-perf': {
+    'tests': [
+      {
+        'isolate': 'performance_test_suite',
+        'extra_args': [
+          # TODO(crbug.com/612455): Enable ref builds once can pass both
+          # --browser=exact (used by this bot to have it run Monochrome6432)
+          # and --browser=reference together.
+          #'--run-ref-build',
+          '--test-shard-map-filename=android-pixel2-perf_map.json',
+        ],
+        'num_shards': 35
+      }
+    ],
+    'platform': 'android-chrome',
+      'browser': 'bin/monochrome_64_32_bundle',
+    'dimension': {
+      'pool': 'chrome.tests.perf',
+      'os': 'Android',
+      'device_type': 'walleye',
+      'device_os': 'O',
+      'device_os_flavor': 'google',
+    },
+  },
   'win-10-perf': {
     'tests': [
       {
diff --git a/tools/perf/core/shard_maps/android-pixel2-perf_map.json b/tools/perf/core/shard_maps/android-pixel2-perf_map.json
index 4a6f40b..3bb0b1c2 100644
--- a/tools/perf/core/shard_maps/android-pixel2-perf_map.json
+++ b/tools/perf/core/shard_maps/android-pixel2-perf_map.json
@@ -3,99 +3,357 @@
         "benchmarks": {
             "blink_perf.accessibility": {},
             "blink_perf.bindings": {},
-            "blink_perf.canvas": {},
-            "blink_perf.css": {},
-            "blink_perf.dom": {},
-            "blink_perf.events": {},
-            "blink_perf.image_decoder": {},
-            "blink_perf.layout": {},
-            "blink_perf.owp_storage": {},
-            "blink_perf.paint": {},
-            "blink_perf.parser": {},
-            "blink_perf.shadow_dom": {},
-            "blink_perf.svg": {},
-            "dromaeo": {},
-            "dummy_benchmark.noisy_benchmark_1": {},
-            "dummy_benchmark.stable_benchmark_1": {}
+            "blink_perf.canvas": {
+                "end": 14
+            }
         }
     },
     "1": {
         "benchmarks": {
-            "jetstream": {},
-            "kraken": {},
-            "loading.mobile": {},
-            "media.mobile": {
-                "end": 21
+            "blink_perf.canvas": {
+                "begin": 14
+            },
+            "blink_perf.css": {},
+            "blink_perf.dom": {
+                "end": 2
             }
         }
     },
     "2": {
         "benchmarks": {
-            "media.mobile": {
-                "begin": 21
+            "blink_perf.dom": {
+                "begin": 2
             },
-            "memory.top_10_mobile": {},
-            "octane": {},
-            "power.typical_10_mobile": {},
-            "rasterize_and_record_micro.partial_invalidation": {},
-            "rasterize_and_record_micro.top_25": {},
-            "rendering.mobile": {
-                "end": 98
+            "blink_perf.events": {},
+            "blink_perf.image_decoder": {},
+            "blink_perf.layout": {
+                "end": 29
             }
         }
     },
     "3": {
         "benchmarks": {
-            "rendering.mobile": {
-                "begin": 98
+            "blink_perf.layout": {
+                "begin": 29
             },
-            "speedometer": {},
-            "speedometer-future": {}
+            "blink_perf.owp_storage": {},
+            "blink_perf.paint": {
+                "end": 1
+            }
         }
     },
     "4": {
         "benchmarks": {
-            "speedometer2": {},
-            "speedometer2-future": {},
-            "startup.mobile": {},
-            "system_health.common_mobile": {},
-            "system_health.memory_mobile": {
-                "end": 19
+            "blink_perf.paint": {
+                "begin": 1
+            },
+            "blink_perf.parser": {},
+            "blink_perf.shadow_dom": {
+                "end": 7
             }
         }
     },
     "5": {
         "benchmarks": {
-            "system_health.memory_mobile": {
-                "begin": 19,
-                "end": 78
-            }
+            "blink_perf.shadow_dom": {
+                "begin": 7
+            },
+            "blink_perf.svg": {},
+            "dromaeo": {},
+            "dummy_benchmark.noisy_benchmark_1": {},
+            "dummy_benchmark.stable_benchmark_1": {},
+            "jetstream": {}
         }
     },
     "6": {
         "benchmarks": {
+            "kraken": {},
+            "loading.mobile": {
+                "end": 20
+            }
+        }
+    },
+    "7": {
+        "benchmarks": {
+            "loading.mobile": {
+                "begin": 20,
+                "end": 37
+            }
+        }
+    },
+    "8": {
+        "benchmarks": {
+            "loading.mobile": {
+                "begin": 37,
+                "end": 61
+            }
+        }
+    },
+    "9": {
+        "benchmarks": {
+            "loading.mobile": {
+                "begin": 61,
+                "end": 80
+            }
+        }
+    },
+    "10": {
+        "benchmarks": {
+            "loading.mobile": {
+                "begin": 80
+            }
+        }
+    },
+    "11": {
+        "benchmarks": {
+            "media.mobile": {},
+            "memory.top_10_mobile": {
+                "end": 5
+            }
+        }
+    },
+    "12": {
+        "benchmarks": {
+            "memory.top_10_mobile": {
+                "begin": 5,
+                "end": 16
+            }
+        }
+    },
+    "13": {
+        "benchmarks": {
+            "memory.top_10_mobile": {
+                "begin": 16
+            },
+            "octane": {},
+            "power.typical_10_mobile": {
+                "end": 10
+            }
+        }
+    },
+    "14": {
+        "benchmarks": {
+            "power.typical_10_mobile": {
+                "begin": 10
+            },
+            "rasterize_and_record_micro.partial_invalidation": {},
+            "rasterize_and_record_micro.top_25": {},
+            "rendering.mobile": {
+                "end": 12
+            }
+        }
+    },
+    "15": {
+        "benchmarks": {
+            "rendering.mobile": {
+                "begin": 12,
+                "end": 63
+            }
+        }
+    },
+    "16": {
+        "benchmarks": {
+            "rendering.mobile": {
+                "begin": 63,
+                "end": 111
+            }
+        }
+    },
+    "17": {
+        "benchmarks": {
+            "rendering.mobile": {
+                "begin": 111,
+                "end": 156
+            }
+        }
+    },
+    "18": {
+        "benchmarks": {
+            "rendering.mobile": {
+                "begin": 156,
+                "end": 206
+            }
+        }
+    },
+    "19": {
+        "benchmarks": {
+            "rendering.mobile": {
+                "begin": 206,
+                "end": 271
+            }
+        }
+    },
+    "20": {
+        "benchmarks": {
+            "rendering.mobile": {
+                "begin": 271,
+                "end": 320
+            }
+        }
+    },
+    "21": {
+        "benchmarks": {
+            "rendering.mobile": {
+                "begin": 320
+            },
+            "speedometer": {},
+            "speedometer-future": {},
+            "speedometer2": {},
+            "speedometer2-future": {}
+        }
+    },
+    "22": {
+        "benchmarks": {
+            "startup.mobile": {},
+            "system_health.common_mobile": {
+                "end": 16
+            }
+        }
+    },
+    "23": {
+        "benchmarks": {
+            "system_health.common_mobile": {
+                "begin": 16,
+                "end": 48
+            }
+        }
+    },
+    "24": {
+        "benchmarks": {
+            "system_health.common_mobile": {
+                "begin": 48
+            },
             "system_health.memory_mobile": {
-                "begin": 78
+                "end": 6
+            }
+        }
+    },
+    "25": {
+        "benchmarks": {
+            "system_health.memory_mobile": {
+                "begin": 6,
+                "end": 15
+            }
+        }
+    },
+    "26": {
+        "benchmarks": {
+            "system_health.memory_mobile": {
+                "begin": 15,
+                "end": 20
+            }
+        }
+    },
+    "27": {
+        "benchmarks": {
+            "system_health.memory_mobile": {
+                "begin": 20,
+                "end": 28
+            }
+        }
+    },
+    "28": {
+        "benchmarks": {
+            "system_health.memory_mobile": {
+                "begin": 28,
+                "end": 44
+            }
+        }
+    },
+    "29": {
+        "benchmarks": {
+            "system_health.memory_mobile": {
+                "begin": 44,
+                "end": 59
+            }
+        }
+    },
+    "30": {
+        "benchmarks": {
+            "system_health.memory_mobile": {
+                "begin": 59,
+                "end": 65
+            }
+        }
+    },
+    "31": {
+        "benchmarks": {
+            "system_health.memory_mobile": {
+                "begin": 65
             },
             "system_health.webview_startup": {},
             "tracing.tracing_with_background_memory_infra": {},
-            "v8.browsing_mobile": {},
-            "v8.browsing_mobile-future": {},
+            "v8.browsing_mobile": {
+                "end": 11
+            }
+        }
+    },
+    "32": {
+        "benchmarks": {
+            "v8.browsing_mobile": {
+                "begin": 11,
+                "end": 27
+            }
+        }
+    },
+    "33": {
+        "benchmarks": {
+            "v8.browsing_mobile": {
+                "begin": 27
+            },
+            "v8.browsing_mobile-future": {
+                "end": 18
+            }
+        }
+    },
+    "34": {
+        "benchmarks": {
+            "v8.browsing_mobile-future": {
+                "begin": 18
+            },
             "webrtc": {}
         }
     },
     "extra_infos": {
-        "num_stories": 1151,
-        "predicted_min_shard_time": 10376.0,
+        "num_stories": 1120,
+        "predicted_min_shard_time": 1932.0,
         "predicted_min_shard_index": 6,
-        "predicted_max_shard_time": 10752.0,
-        "predicted_max_shard_index": 1,
-        "shard #0": 10414.0,
-        "shard #1": 10752.0,
-        "shard #2": 10566.0,
-        "shard #3": 10538.0,
-        "shard #4": 10686.0,
-        "shard #5": 10698.0,
-        "shard #6": 10376.0
+        "predicted_max_shard_time": 2420.0,
+        "predicted_max_shard_index": 5,
+        "shard #0": 2172.0,
+        "shard #1": 2152.0,
+        "shard #2": 2150.0,
+        "shard #3": 2180.0,
+        "shard #4": 2146.0,
+        "shard #5": 2420.0,
+        "shard #6": 1932.0,
+        "shard #7": 2020.0,
+        "shard #8": 2252.0,
+        "shard #9": 2152.0,
+        "shard #10": 2268.0,
+        "shard #11": 2012.0,
+        "shard #12": 2140.0,
+        "shard #13": 2248.0,
+        "shard #14": 2142.0,
+        "shard #15": 2130.0,
+        "shard #16": 2184.0,
+        "shard #17": 2152.0,
+        "shard #18": 2146.0,
+        "shard #19": 2184.0,
+        "shard #20": 2160.0,
+        "shard #21": 2130.0,
+        "shard #22": 2166.0,
+        "shard #23": 2192.0,
+        "shard #24": 2162.0,
+        "shard #25": 2046.0,
+        "shard #26": 2124.0,
+        "shard #27": 2202.0,
+        "shard #28": 2304.0,
+        "shard #29": 2004.0,
+        "shard #30": 2100.0,
+        "shard #31": 2314.0,
+        "shard #32": 2106.0,
+        "shard #33": 2236.0,
+        "shard #34": 2120.0
     }
 }
\ No newline at end of file
diff --git a/tools/perf/core/shard_maps/android-pixel2_webview-perf_map.json b/tools/perf/core/shard_maps/android-pixel2_webview-perf_map.json
index 7db5908..bcd1c4bf 100644
--- a/tools/perf/core/shard_maps/android-pixel2_webview-perf_map.json
+++ b/tools/perf/core/shard_maps/android-pixel2_webview-perf_map.json
@@ -3,109 +3,295 @@
         "benchmarks": {
             "blink_perf.accessibility": {},
             "blink_perf.bindings": {},
-            "blink_perf.canvas": {},
-            "blink_perf.css": {},
-            "blink_perf.dom": {},
-            "blink_perf.events": {},
-            "blink_perf.image_decoder": {},
-            "blink_perf.layout": {},
-            "blink_perf.owp_storage": {},
-            "blink_perf.paint": {},
-            "blink_perf.parser": {},
-            "blink_perf.shadow_dom": {},
-            "blink_perf.svg": {
-                "end": 2
+            "blink_perf.canvas": {
+                "end": 19
             }
         }
     },
     "1": {
         "benchmarks": {
-            "blink_perf.svg": {
-                "begin": 2
+            "blink_perf.canvas": {
+                "begin": 19
             },
+            "blink_perf.css": {},
+            "blink_perf.dom": {},
+            "blink_perf.events": {},
+            "blink_perf.image_decoder": {
+                "end": 6
+            }
+        }
+    },
+    "2": {
+        "benchmarks": {
+            "blink_perf.image_decoder": {
+                "begin": 6
+            },
+            "blink_perf.layout": {
+                "end": 65
+            }
+        }
+    },
+    "3": {
+        "benchmarks": {
+            "blink_perf.layout": {
+                "begin": 65
+            },
+            "blink_perf.owp_storage": {},
+            "blink_perf.paint": {},
+            "blink_perf.parser": {
+                "end": 27
+            }
+        }
+    },
+    "4": {
+        "benchmarks": {
+            "blink_perf.parser": {
+                "begin": 27
+            },
+            "blink_perf.shadow_dom": {},
+            "blink_perf.svg": {},
             "dromaeo": {},
             "dummy_benchmark.noisy_benchmark_1": {},
             "dummy_benchmark.stable_benchmark_1": {},
-            "jetstream": {},
+            "jetstream": {}
+        }
+    },
+    "5": {
+        "benchmarks": {
             "kraken": {},
-            "loading.mobile": {},
+            "loading.mobile": {
+                "end": 28
+            }
+        }
+    },
+    "6": {
+        "benchmarks": {
+            "loading.mobile": {
+                "begin": 28,
+                "end": 63
+            }
+        }
+    },
+    "7": {
+        "benchmarks": {
+            "loading.mobile": {
+                "begin": 63,
+                "end": 92
+            }
+        }
+    },
+    "8": {
+        "benchmarks": {
+            "loading.mobile": {
+                "begin": 92
+            },
             "media.mobile": {},
             "memory.top_10_mobile": {
                 "end": 9
             }
         }
     },
-    "2": {
+    "9": {
         "benchmarks": {
             "memory.top_10_mobile": {
                 "begin": 9
             },
             "octane": {},
-            "power.typical_10_mobile": {},
-            "rasterize_and_record_micro.partial_invalidation": {},
-            "rasterize_and_record_micro.top_25": {},
-            "rendering.mobile": {
-                "end": 116
+            "power.typical_10_mobile": {
+                "end": 1
             }
         }
     },
-    "3": {
+    "10": {
+        "benchmarks": {
+            "power.typical_10_mobile": {
+                "begin": 1
+            },
+            "rasterize_and_record_micro.partial_invalidation": {},
+            "rasterize_and_record_micro.top_25": {
+                "end": 17
+            }
+        }
+    },
+    "11": {
+        "benchmarks": {
+            "rasterize_and_record_micro.top_25": {
+                "begin": 17
+            },
+            "rendering.mobile": {
+                "end": 46
+            }
+        }
+    },
+    "12": {
         "benchmarks": {
             "rendering.mobile": {
-                "begin": 116
+                "begin": 46,
+                "end": 103
+            }
+        }
+    },
+    "13": {
+        "benchmarks": {
+            "rendering.mobile": {
+                "begin": 103,
+                "end": 161
+            }
+        }
+    },
+    "14": {
+        "benchmarks": {
+            "rendering.mobile": {
+                "begin": 161,
+                "end": 225
+            }
+        }
+    },
+    "15": {
+        "benchmarks": {
+            "rendering.mobile": {
+                "begin": 225,
+                "end": 304
+            }
+        }
+    },
+    "16": {
+        "benchmarks": {
+            "rendering.mobile": {
+                "begin": 304
             },
             "speedometer": {},
             "speedometer-future": {},
-            "speedometer2": {},
+            "speedometer2": {}
+        }
+    },
+    "17": {
+        "benchmarks": {
             "speedometer2-future": {},
             "startup.mobile": {},
             "system_health.common_mobile": {
-                "end": 13
+                "end": 26
             }
         }
     },
-    "4": {
+    "18": {
         "benchmarks": {
             "system_health.common_mobile": {
-                "begin": 13
-            },
+                "begin": 26
+            }
+        }
+    },
+    "19": {
+        "benchmarks": {
             "system_health.memory_mobile": {
+                "end": 14
+            }
+        }
+    },
+    "20": {
+        "benchmarks": {
+            "system_health.memory_mobile": {
+                "begin": 14,
                 "end": 23
             }
         }
     },
-    "5": {
+    "21": {
         "benchmarks": {
             "system_health.memory_mobile": {
                 "begin": 23,
-                "end": 80
+                "end": 34
             }
         }
     },
-    "6": {
+    "22": {
         "benchmarks": {
             "system_health.memory_mobile": {
-                "begin": 80
+                "begin": 34,
+                "end": 51
+            }
+        }
+    },
+    "23": {
+        "benchmarks": {
+            "system_health.memory_mobile": {
+                "begin": 51,
+                "end": 65
+            }
+        }
+    },
+    "24": {
+        "benchmarks": {
+            "system_health.memory_mobile": {
+                "begin": 65
             },
             "system_health.webview_startup": {},
-            "tracing.tracing_with_background_memory_infra": {},
-            "v8.browsing_mobile": {},
-            "v8.browsing_mobile-future": {},
+            "tracing.tracing_with_background_memory_infra": {
+                "end": 6
+            }
+        }
+    },
+    "25": {
+        "benchmarks": {
+            "tracing.tracing_with_background_memory_infra": {
+                "begin": 6
+            },
+            "v8.browsing_mobile": {
+                "end": 21
+            }
+        }
+    },
+    "26": {
+        "benchmarks": {
+            "v8.browsing_mobile": {
+                "begin": 21
+            },
+            "v8.browsing_mobile-future": {
+                "end": 14
+            }
+        }
+    },
+    "27": {
+        "benchmarks": {
+            "v8.browsing_mobile-future": {
+                "begin": 14
+            },
             "webrtc": {}
         }
     },
     "extra_infos": {
-        "num_stories": 1151,
-        "predicted_min_shard_time": 8660.0,
-        "predicted_min_shard_index": 4,
-        "predicted_max_shard_time": 8852.0,
-        "predicted_max_shard_index": 1,
-        "shard #0": 8762.0,
-        "shard #1": 8852.0,
-        "shard #2": 8668.0,
-        "shard #3": 8764.0,
-        "shard #4": 8660.0,
-        "shard #5": 8802.0,
-        "shard #6": 8830.0
+        "num_stories": 1120,
+        "predicted_min_shard_time": 1874.0,
+        "predicted_min_shard_index": 24,
+        "predicted_max_shard_time": 2268.0,
+        "predicted_max_shard_index": 23,
+        "shard #0": 2042.0,
+        "shard #1": 2094.0,
+        "shard #2": 2008.0,
+        "shard #3": 2058.0,
+        "shard #4": 2002.0,
+        "shard #5": 2208.0,
+        "shard #6": 1900.0,
+        "shard #7": 2096.0,
+        "shard #8": 1936.0,
+        "shard #9": 2168.0,
+        "shard #10": 2040.0,
+        "shard #11": 2042.0,
+        "shard #12": 2034.0,
+        "shard #13": 2064.0,
+        "shard #14": 2040.0,
+        "shard #15": 2036.0,
+        "shard #16": 2032.0,
+        "shard #17": 2078.0,
+        "shard #18": 1992.0,
+        "shard #19": 2088.0,
+        "shard #20": 2052.0,
+        "shard #21": 2100.0,
+        "shard #22": 1968.0,
+        "shard #23": 2268.0,
+        "shard #24": 1874.0,
+        "shard #25": 2040.0,
+        "shard #26": 2124.0,
+        "shard #27": 1980.0
     }
 }
\ No newline at end of file
diff --git a/tools/perf/core/shard_maps/timing_data/android-pixel2-perf_timing.json b/tools/perf/core/shard_maps/timing_data/android-pixel2-perf_timing.json
index c9a069c..0d17406 100644
--- a/tools/perf/core/shard_maps/timing_data/android-pixel2-perf_timing.json
+++ b/tools/perf/core/shard_maps/timing_data/android-pixel2-perf_timing.json
@@ -1,282 +1,282 @@
 [
     {
-        "duration": "29.0",
+        "duration": "31.0",
         "name": "blink_perf.accessibility/line-breaks.html"
     },
     {
-        "duration": "22.0",
+        "duration": "27.0",
         "name": "blink_perf.accessibility/textarea-append.html"
     },
     {
-        "duration": "19.0",
+        "duration": "21.0",
         "name": "blink_perf.bindings/append-child.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.bindings/create-element.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.bindings/document-implementation.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.bindings/dom-attribute-on-prototoype.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.bindings/first-child.html"
     },
     {
-        "duration": "11.0",
+        "duration": "14.0",
         "name": "blink_perf.bindings/gc-forest.html"
     },
     {
-        "duration": "13.0",
+        "duration": "14.0",
         "name": "blink_perf.bindings/gc-mini-tree.html"
     },
     {
-        "duration": "28.0",
+        "duration": "42.0",
         "name": "blink_perf.bindings/gc-tree.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.bindings/get-attribute-rare.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.bindings/get-attribute.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.bindings/get-element-by-id.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.bindings/get-elements-by-tag-name.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.bindings/id-getter.html"
     },
     {
-        "duration": "12.0",
+        "duration": "16.0",
         "name": "blink_perf.bindings/id-setter.html"
     },
     {
-        "duration": "13.0",
+        "duration": "16.0",
         "name": "blink_perf.bindings/indexed-getter.html"
     },
     {
-        "duration": "12.0",
+        "duration": "14.0",
         "name": "blink_perf.bindings/insert-before.html"
     },
     {
-        "duration": "13.0",
+        "duration": "17.0",
         "name": "blink_perf.bindings/named-property-enumerator.html"
     },
     {
-        "duration": "20.0",
+        "duration": "28.0",
         "name": "blink_perf.bindings/node-list-access.html"
     },
     {
-        "duration": "12.0",
+        "duration": "14.0",
         "name": "blink_perf.bindings/node-type.html"
     },
     {
-        "duration": "8.0",
+        "duration": "11.0",
         "name": "blink_perf.bindings/post-message.html"
     },
     {
-        "duration": "12.0",
+        "duration": "16.0",
         "name": "blink_perf.bindings/sequence-conversion-array.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.bindings/sequence-conversion-custom-iterator.html"
     },
     {
-        "duration": "7.0",
+        "duration": "10.0",
         "name": "blink_perf.bindings/serialize-array.html"
     },
     {
-        "duration": "6.0",
+        "duration": "9.0",
         "name": "blink_perf.bindings/serialize-long-string.html"
     },
     {
-        "duration": "10.0",
+        "duration": "12.0",
         "name": "blink_perf.bindings/serialize-map.html"
     },
     {
-        "duration": "6.0",
+        "duration": "9.0",
         "name": "blink_perf.bindings/serialize-nested-array.html"
     },
     {
-        "duration": "12.0",
+        "duration": "14.0",
         "name": "blink_perf.bindings/set-attribute-rare.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.bindings/set-attribute.html"
     },
     {
-        "duration": "18.0",
+        "duration": "21.0",
         "name": "blink_perf.bindings/structured-clone-json-deserialize.html"
     },
     {
-        "duration": "19.0",
+        "duration": "21.0",
         "name": "blink_perf.bindings/structured-clone-json-serialize.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.bindings/typed-array-construct-from-array.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.bindings/typed-array-construct-from-same-type.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.bindings/typed-array-construct-from-typed.html"
     },
     {
-        "duration": "12.0",
+        "duration": "14.0",
         "name": "blink_perf.bindings/typed-array-set-from-typed.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.bindings/undefined-first-child.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.bindings/undefined-get-element-by-id.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.bindings/undefined-id-getter.html"
     },
     {
-        "duration": "6.0",
+        "duration": "8.0",
         "name": "blink_perf.bindings/worker-structured-clone-different-payloads.html"
     },
     {
-        "duration": "31.0",
+        "duration": "32.0",
         "name": "blink_perf.bindings/worker-structured-clone-json-from-worker.html"
     },
     {
-        "duration": "31.0",
+        "duration": "39.0",
         "name": "blink_perf.bindings/worker-structured-clone-json-roundtrip.html"
     },
     {
-        "duration": "31.0",
+        "duration": "32.0",
         "name": "blink_perf.bindings/worker-structured-clone-json-to-worker.html"
     },
     {
-        "duration": "10.0",
+        "duration": "12.0",
         "name": "blink_perf.bindings/worker-structured-clone-workerDOM-DBMon-from-worker.html"
     },
     {
-        "duration": "7.0",
+        "duration": "8.0",
         "name": "blink_perf.bindings/worker-structured-clone-workerDOM-Map-from-worker.html"
     },
     {
-        "duration": "66.0",
+        "duration": "20.0",
         "name": "blink_perf.bindings/worker-text-encoded-transferable-from-worker.html"
     },
     {
-        "duration": "66.0",
+        "duration": "22.0",
         "name": "blink_perf.bindings/worker-text-encoded-transferable-roundtrip.html"
     },
     {
-        "duration": "65.0",
+        "duration": "21.0",
         "name": "blink_perf.bindings/worker-text-encoded-transferable-to-worker.html"
     },
     {
-        "duration": "15.0",
+        "duration": "16.0",
         "name": "blink_perf.bindings/worker-transferable-from-worker.html"
     },
     {
-        "duration": "15.0",
+        "duration": "17.0",
         "name": "blink_perf.bindings/worker-transferable-roundtrip.html"
     },
     {
-        "duration": "14.0",
+        "duration": "16.0",
         "name": "blink_perf.bindings/worker-transferable-to-worker.html"
     },
     {
-        "duration": "18.0",
+        "duration": "21.0",
         "name": "blink_perf.canvas/createImageBitmapFromImageData.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.canvas/createImageBitmapFromImageData_RAF.html?RAF"
     },
     {
-        "duration": "14.0",
+        "duration": "16.0",
         "name": "blink_perf.canvas/docs-paper.html"
     },
     {
-        "duration": "9.0",
+        "duration": "11.0",
         "name": "blink_perf.canvas/docs-paper_RAF.html?RAF"
     },
     {
-        "duration": "14.0",
+        "duration": "17.0",
         "name": "blink_perf.canvas/docs-resume.html"
     },
     {
-        "duration": "9.0",
+        "duration": "10.0",
         "name": "blink_perf.canvas/docs-resume_RAF.html?RAF"
     },
     {
-        "duration": "12.0",
+        "duration": "16.0",
         "name": "blink_perf.canvas/docs-table.html"
     },
     {
-        "duration": "8.0",
+        "duration": "11.0",
         "name": "blink_perf.canvas/docs-table_RAF.html?RAF"
     },
     {
-        "duration": "8.0",
+        "duration": "11.0",
         "name": "blink_perf.canvas/draw-dynamic-canvas-2d-to-hw-accelerated-canvas-2d.html"
     },
     {
-        "duration": "8.0",
+        "duration": "10.0",
         "name": "blink_perf.canvas/draw-dynamic-canvas-2d-to-hw-accelerated-canvas-2d_RAF.html?RAF"
     },
     {
-        "duration": "13.0",
+        "duration": "16.0",
         "name": "blink_perf.canvas/draw-dynamic-webgl-to-hw-accelerated-canvas-2d.html"
     },
     {
-        "duration": "9.0",
+        "duration": "11.0",
         "name": "blink_perf.canvas/draw-dynamic-webgl-to-hw-accelerated-canvas-2d_RAF.html?RAF"
     },
     {
-        "duration": "7.0",
+        "duration": "9.0",
         "name": "blink_perf.canvas/draw-hw-accelerated-canvas-2d-to-sw-canvas-2d.html"
     },
     {
-        "duration": "8.0",
+        "duration": "12.0",
         "name": "blink_perf.canvas/draw-hw-accelerated-canvas-2d-to-sw-canvas-2d_RAF.html?RAF"
     },
     {
-        "duration": "7.0",
+        "duration": "9.0",
         "name": "blink_perf.canvas/draw-static-canvas-2d-to-hw-accelerated-canvas-2d.html"
     },
     {
-        "duration": "9.0",
+        "duration": "11.0",
         "name": "blink_perf.canvas/draw-static-canvas-2d-to-hw-accelerated-canvas-2d_RAF.html?RAF"
     },
     {
-        "duration": "7.0",
+        "duration": "9.0",
         "name": "blink_perf.canvas/draw-static-webgl-to-hw-accelerated-canvas-2d.html"
     },
     {
-        "duration": "9.0",
+        "duration": "12.0",
         "name": "blink_perf.canvas/draw-static-webgl-to-hw-accelerated-canvas-2d_RAF.html?RAF"
     },
     {
-        "duration": "8.0",
+        "duration": "10.0",
         "name": "blink_perf.canvas/draw-video-to-hw-accelerated-canvas-2d.html"
     },
     {
@@ -284,55 +284,55 @@
         "name": "blink_perf.canvas/draw-video-to-hw-accelerated-canvas-2d_RAF.html?RAF"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.canvas/drawimage-not-pixelaligned.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.canvas/drawimage-not-pixelaligned_RAF.html?RAF"
     },
     {
-        "duration": "12.0",
+        "duration": "16.0",
         "name": "blink_perf.canvas/drawimage.html"
     },
     {
-        "duration": "13.0",
+        "duration": "16.0",
         "name": "blink_perf.canvas/drawimage_RAF.html?RAF"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.canvas/getImageData.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.canvas/getImageDataColorManaged.html"
     },
     {
-        "duration": "12.0",
+        "duration": "14.0",
         "name": "blink_perf.canvas/getImageDataColorManaged_RAF.html?RAF"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.canvas/getImageData_RAF.html?RAF"
     },
     {
-        "duration": "6.0",
+        "duration": "8.0",
         "name": "blink_perf.canvas/gpu-bound-shader.html"
     },
     {
-        "duration": "9.0",
+        "duration": "11.0",
         "name": "blink_perf.canvas/gpu-bound-shader_RAF.html?RAF"
     },
     {
-        "duration": "12.0",
+        "duration": "14.0",
         "name": "blink_perf.canvas/putImageData.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.canvas/putImageData_RAF.html?RAF"
     },
     {
-        "duration": "15.0",
+        "duration": "18.0",
         "name": "blink_perf.canvas/sheets-render.html"
     },
     {
@@ -340,75 +340,75 @@
         "name": "blink_perf.canvas/sheets-render_RAF.html?RAF"
     },
     {
-        "duration": "12.0",
+        "duration": "14.0",
         "name": "blink_perf.canvas/toBlob_duration.html"
     },
     {
-        "duration": "11.0",
+        "duration": "14.0",
         "name": "blink_perf.canvas/toBlob_duration_RAF.html?RAF"
     },
     {
-        "duration": "9.0",
+        "duration": "10.0",
         "name": "blink_perf.canvas/toBlob_duration_jpeg.html"
     },
     {
-        "duration": "10.0",
+        "duration": "11.0",
         "name": "blink_perf.canvas/toBlob_duration_jpeg_RAF.html?RAF"
     },
     {
-        "duration": "7.0",
+        "duration": "11.0",
         "name": "blink_perf.canvas/transferFromImageBitmap.html"
     },
     {
-        "duration": "8.0",
+        "duration": "12.0",
         "name": "blink_perf.canvas/transferFromImageBitmap_RAF.html?RAF"
     },
     {
-        "duration": "9.0",
+        "duration": "12.0",
         "name": "blink_perf.canvas/upload-canvas-2d-to-texture.html"
     },
     {
-        "duration": "13.0",
+        "duration": "16.0",
         "name": "blink_perf.canvas/upload-canvas-2d-to-texture_RAF.html?RAF"
     },
     {
-        "duration": "14.0",
+        "duration": "15.0",
         "name": "blink_perf.canvas/upload-video-to-sub-texture.html"
     },
     {
-        "duration": "9.0",
+        "duration": "11.0",
         "name": "blink_perf.canvas/upload-video-to-sub-texture_RAF.html?RAF"
     },
     {
-        "duration": "10.0",
+        "duration": "12.0",
         "name": "blink_perf.canvas/upload-video-to-texture.html"
     },
     {
-        "duration": "11.0",
+        "duration": "13.0",
         "name": "blink_perf.canvas/upload-video-to-texture_RAF.html?RAF"
     },
     {
-        "duration": "7.0",
+        "duration": "10.0",
         "name": "blink_perf.canvas/upload-webgl-to-texture.html"
     },
     {
-        "duration": "11.0",
+        "duration": "13.0",
         "name": "blink_perf.canvas/upload-webgl-to-texture_RAF.html?RAF"
     },
     {
-        "duration": "22.0",
+        "duration": "24.0",
         "name": "blink_perf.css/AttributeDescendantSelector.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.css/CSSPropertySetterGetter.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.css/CSSPropertySetterGetterMethods.html"
     },
     {
-        "duration": "14.0",
+        "duration": "15.0",
         "name": "blink_perf.css/CSSPropertyUpdateValue.html"
     },
     {
@@ -416,31 +416,31 @@
         "name": "blink_perf.css/ChangeStyleChildClassSelector.html"
     },
     {
-        "duration": "16.0",
+        "duration": "17.0",
         "name": "blink_perf.css/ChangeStyleChildElementSelectors.html"
     },
     {
-        "duration": "16.0",
+        "duration": "19.0",
         "name": "blink_perf.css/ChangeStyleElementSelector.html"
     },
     {
-        "duration": "16.0",
+        "duration": "19.0",
         "name": "blink_perf.css/ChangeStyleGrandChildElementSelector.html"
     },
     {
-        "duration": "16.0",
+        "duration": "18.0",
         "name": "blink_perf.css/ChangeStyleMultipleClassSelector.html"
     },
     {
-        "duration": "16.0",
+        "duration": "18.0",
         "name": "blink_perf.css/ChangeStyleMultipleQualifiedDataAttributesWithValuesSelector.html"
     },
     {
-        "duration": "16.0",
+        "duration": "19.0",
         "name": "blink_perf.css/ChangeStyleNestedPseudoSelector.html"
     },
     {
-        "duration": "15.0",
+        "duration": "16.0",
         "name": "blink_perf.css/ChangeStylePairOfNthChildSelector.html"
     },
     {
@@ -448,267 +448,263 @@
         "name": "blink_perf.css/ChangeStylePartialAttributeMatchingSelector.html"
     },
     {
-        "duration": "17.0",
+        "duration": "19.0",
         "name": "blink_perf.css/ChangeStyleQualifiedDataAttributeSelector.html"
     },
     {
-        "duration": "16.0",
+        "duration": "20.0",
         "name": "blink_perf.css/ChangeStyleQualifiedDataAttributeWithValueSelector.html"
     },
     {
-        "duration": "16.0",
+        "duration": "18.0",
         "name": "blink_perf.css/ChangeStyleShallowTree.html"
     },
     {
-        "duration": "15.0",
+        "duration": "17.0",
         "name": "blink_perf.css/ChangeStyleSingleClassSelector.html"
     },
     {
-        "duration": "16.0",
+        "duration": "18.0",
         "name": "blink_perf.css/ChangeStyleSingleNthChildSelector.html"
     },
     {
-        "duration": "16.0",
+        "duration": "18.0",
         "name": "blink_perf.css/ChangeStyleSinglePseudoSelector.html"
     },
     {
-        "duration": "16.0",
+        "duration": "19.0",
         "name": "blink_perf.css/ChangeStyleUniversalSelector.html"
     },
     {
-        "duration": "16.0",
+        "duration": "17.0",
         "name": "blink_perf.css/ChangeStyleUnqualifiedDataAttributeSelector.html"
     },
     {
-        "duration": "16.0",
+        "duration": "20.0",
         "name": "blink_perf.css/ChangeStyleUnqualifiedDataAttributeWithValueSelector.html"
     },
     {
-        "duration": "15.0",
+        "duration": "21.0",
         "name": "blink_perf.css/ClassDescendantSelector.html"
     },
     {
-        "duration": "14.0",
+        "duration": "17.0",
         "name": "blink_perf.css/ClassInvalidation.html"
     },
     {
-        "duration": "10.0",
+        "duration": "13.0",
         "name": "blink_perf.css/CustomPropertiesCascade.html"
     },
     {
-        "duration": "7.0",
+        "duration": "10.0",
         "name": "blink_perf.css/CustomPropertiesNonRootInheritance.html"
     },
     {
-        "duration": "7.0",
+        "duration": "10.0",
         "name": "blink_perf.css/CustomPropertiesRootInheritance.html"
     },
     {
-        "duration": "7.0",
+        "duration": "9.0",
         "name": "blink_perf.css/CustomPropertiesVarAlias.html"
     },
     {
-        "duration": "15.0",
+        "duration": "18.0",
         "name": "blink_perf.css/FocusUpdate.html"
     },
     {
-        "duration": "15.0",
+        "duration": "17.0",
         "name": "blink_perf.css/LoadBootstrapBlog.html"
     },
     {
-        "duration": "15.0",
+        "duration": "17.0",
         "name": "blink_perf.css/LoadMaterializeStarterPage.html"
     },
     {
-        "duration": "15.0",
+        "duration": "19.0",
         "name": "blink_perf.css/LoadSemanticPageExample.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.css/PseudoClassSelectors.html"
     },
     {
-        "duration": "16.0",
+        "duration": "19.0",
         "name": "blink_perf.css/SelectorCountScaling.html"
     },
     {
-        "duration": "35.0",
+        "duration": "44.0",
         "name": "blink_perf.dom/custom-element-default-style-with-shadow.html"
     },
     {
-        "duration": "26.0",
+        "duration": "30.0",
         "name": "blink_perf.dom/custom-element-default-style.html"
     },
     {
-        "duration": "33.0",
+        "duration": "23.0",
         "name": "blink_perf.dom/long-sibling-list.html"
     },
     {
-        "duration": "9.0",
+        "duration": "12.0",
         "name": "blink_perf.dom/modify-element-classname.html"
     },
     {
-        "duration": "8.0",
+        "duration": "11.0",
         "name": "blink_perf.dom/modify-element-id.html"
     },
     {
-        "duration": "8.0",
+        "duration": "10.0",
         "name": "blink_perf.dom/modify-element-title.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.dom/select-multiple-add.html"
     },
     {
-        "duration": "14.0",
+        "duration": "16.0",
         "name": "blink_perf.dom/select-single-add.html"
     },
     {
-        "duration": "12.0",
+        "duration": "14.0",
         "name": "blink_perf.dom/select-single-remove.html"
     },
     {
-        "duration": "22.0",
+        "duration": "26.0",
         "name": "blink_perf.events/EventsDispatching.html"
     },
     {
-        "duration": "13.0",
-        "name": "blink_perf.events/EventsDispatchingInDeeplyNestedV0ShadowTrees.html"
-    },
-    {
-        "duration": "14.0",
-        "name": "blink_perf.events/EventsDispatchingInDeeplyNestedV1ShadowTrees.html"
-    },
-    {
-        "duration": "23.0",
-        "name": "blink_perf.events/EventsDispatchingInV0ShadowTrees.html"
-    },
-    {
-        "duration": "23.0",
-        "name": "blink_perf.events/EventsDispatchingInV1ShadowTrees.html"
-    },
-    {
-        "duration": "24.0",
+        "duration": "35.0",
         "name": "blink_perf.events/hit-test-lots-of-layers.html"
     },
     {
-        "duration": "14.0",
+        "duration": "19.0",
         "name": "blink_perf.events/is-input-pending-all-events.html"
     },
     {
-        "duration": "15.0",
+        "duration": "20.0",
         "name": "blink_perf.events/is-input-pending-default-events.html"
     },
     {
-        "duration": "50.0",
+        "duration": "56.0",
         "name": "blink_perf.image_decoder/decode-gif.html"
     },
     {
-        "duration": "20.0",
-        "name": "blink_perf.image_decoder/decode-jpeg.html"
+        "duration": "29.0",
+        "name": "blink_perf.image_decoder/decode-jpeg-h1v1.html"
     },
     {
-        "duration": "51.0",
-        "name": "blink_perf.image_decoder/decode-lossless-webp.html"
+        "duration": "25.0",
+        "name": "blink_perf.image_decoder/decode-jpeg-h1v2.html"
     },
     {
-        "duration": "15.0",
-        "name": "blink_perf.image_decoder/decode-lossy-webp.html"
+        "duration": "26.0",
+        "name": "blink_perf.image_decoder/decode-jpeg-h2v1.html"
     },
     {
-        "duration": "34.0",
-        "name": "blink_perf.image_decoder/decode-png-palette-opaque.html"
-    },
-    {
-        "duration": "22.0",
-        "name": "blink_perf.image_decoder/decode-png-palette.html"
+        "duration": "23.0",
+        "name": "blink_perf.image_decoder/decode-jpeg-h2v2.html"
     },
     {
         "duration": "56.0",
-        "name": "blink_perf.image_decoder/decode-png.html"
+        "name": "blink_perf.image_decoder/decode-lossless-webp.html"
     },
     {
         "duration": "18.0",
+        "name": "blink_perf.image_decoder/decode-lossy-webp.html"
+    },
+    {
+        "duration": "41.0",
+        "name": "blink_perf.image_decoder/decode-png-palette-opaque.html"
+    },
+    {
+        "duration": "26.0",
+        "name": "blink_perf.image_decoder/decode-png-palette.html"
+    },
+    {
+        "duration": "62.0",
+        "name": "blink_perf.image_decoder/decode-png.html"
+    },
+    {
+        "duration": "21.0",
         "name": "blink_perf.layout/ArabicLineLayout.html"
     },
     {
-        "duration": "7.0",
+        "duration": "9.0",
         "name": "blink_perf.layout/Shapes/MultipleShapes.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.layout/SimpleTextPathLineLayout.html"
     },
     {
-        "duration": "12.0",
+        "duration": "18.0",
         "name": "blink_perf.layout/add-remove-inline-floats.html"
     },
     {
-        "duration": "13.0",
+        "duration": "10.0",
+        "name": "blink_perf.layout/animate-abspos-deep.html"
+    },
+    {
+        "duration": "16.0",
         "name": "blink_perf.layout/attach-inlines-2.html"
     },
     {
-        "duration": "13.0",
+        "duration": "14.0",
         "name": "blink_perf.layout/attach-inlines.html"
     },
     {
-        "duration": "14.0",
+        "duration": "16.0",
         "name": "blink_perf.layout/auto-grid-lots-of-data.html"
     },
     {
-        "duration": "17.0",
+        "duration": "69.0",
         "name": "blink_perf.layout/change-text-css-contain.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.layout/chapter-reflow-once-random.html"
     },
     {
-        "duration": "12.0",
+        "duration": "14.0",
         "name": "blink_perf.layout/chapter-reflow-once.html"
     },
     {
-        "duration": "13.0",
+        "duration": "14.0",
         "name": "blink_perf.layout/chapter-reflow-thrice.html"
     },
     {
-        "duration": "14.0",
+        "duration": "17.0",
         "name": "blink_perf.layout/chapter-reflow-twice.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.layout/chapter-reflow.html"
     },
     {
-        "duration": "17.0",
+        "duration": "13.0",
         "name": "blink_perf.layout/character_fallback.html"
     },
     {
-        "duration": "7.0",
-        "name": "blink_perf.layout/character_fallback_aat.html"
-    },
-    {
-        "duration": "17.0",
+        "duration": "15.0",
         "name": "blink_perf.layout/contain-content-style-change.html"
     },
     {
-        "duration": "13.0",
+        "duration": "21.0",
         "name": "blink_perf.layout/fit-content-change-available-size-blocks.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.layout/fit-content-change-available-size-text.html"
     },
     {
-        "duration": "14.0",
+        "duration": "17.0",
         "name": "blink_perf.layout/fixed-grid-lots-of-data.html"
     },
     {
-        "duration": "14.0",
+        "duration": "17.0",
         "name": "blink_perf.layout/fixed-grid-lots-of-stretched-data.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.layout/flexbox-column-nowrap.html"
     },
     {
@@ -716,715 +712,695 @@
         "name": "blink_perf.layout/flexbox-column-wrap.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.layout/flexbox-deeply-nested-column-flow.html"
     },
     {
-        "duration": "13.0",
+        "duration": "17.0",
         "name": "blink_perf.layout/flexbox-lots-of-data.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.layout/flexbox-row-nowrap.html"
     },
     {
-        "duration": "15.0",
+        "duration": "19.0",
         "name": "blink_perf.layout/flexbox-row-stretch-height-definite.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.layout/flexbox-row-wrap.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.layout/flexbox-with-stretch-layout.html"
     },
     {
-        "duration": "17.0",
+        "duration": "23.0",
         "name": "blink_perf.layout/floats_100_100.html"
     },
     {
-        "duration": "17.0",
+        "duration": "23.0",
         "name": "blink_perf.layout/floats_100_100_nested.html"
     },
     {
-        "duration": "14.0",
+        "duration": "18.0",
         "name": "blink_perf.layout/floats_10_1000.html"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "blink_perf.layout/floats_20_100.html"
     },
     {
-        "duration": "11.0",
+        "duration": "14.0",
         "name": "blink_perf.layout/floats_20_100_nested.html"
     },
     {
-        "duration": "8.0",
+        "duration": "11.0",
         "name": "blink_perf.layout/floats_2_100.html"
     },
     {
-        "duration": "9.0",
+        "duration": "13.0",
         "name": "blink_perf.layout/floats_2_100_nested.html"
     },
     {
-        "duration": "11.0",
+        "duration": "13.0",
         "name": "blink_perf.layout/floats_50_100.html"
     },
     {
-        "duration": "12.0",
+        "duration": "14.0",
         "name": "blink_perf.layout/floats_50_100_nested.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.layout/hindi-line-layout.html"
     },
     {
-        "duration": "8.0",
+        "duration": "13.0",
         "name": "blink_perf.layout/japanese-kokoro-insert.html"
     },
     {
-        "duration": "16.0",
+        "duration": "21.0",
         "name": "blink_perf.layout/large-grid.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.layout/large-spanning-grid-item.html"
     },
     {
-        "duration": "17.0",
+        "duration": "23.0",
         "name": "blink_perf.layout/large-table-with-collapsed-borders-and-colspans-wider-than-table.html"
     },
     {
-        "duration": "16.0",
+        "duration": "23.0",
         "name": "blink_perf.layout/large-table-with-collapsed-borders-and-colspans.html"
     },
     {
-        "duration": "16.0",
+        "duration": "23.0",
         "name": "blink_perf.layout/large-table-with-collapsed-borders-and-no-colspans.html"
     },
     {
-        "duration": "46.0",
+        "duration": "31.0",
         "name": "blink_perf.layout/latin-ebook-resize.html"
     },
     {
-        "duration": "12.0",
+        "duration": "14.0",
         "name": "blink_perf.layout/latin-ebook.html"
     },
     {
-        "duration": "8.0",
+        "duration": "11.0",
         "name": "blink_perf.layout/layers_overlap_2d.html"
     },
     {
-        "duration": "8.0",
+        "duration": "11.0",
         "name": "blink_perf.layout/layers_overlap_3d.html"
     },
     {
-        "duration": "8.0",
+        "duration": "198.0",
         "name": "blink_perf.layout/line-layout-fit-content-break-word.html"
     },
     {
-        "duration": "11.0",
-        "name": "blink_perf.layout/line-layout-fit-content.html"
-    },
-    {
-        "duration": "17.0",
+        "duration": "21.0",
         "name": "blink_perf.layout/line-layout-line-height.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.layout/line-layout-repeat-append-select.html"
     },
     {
-        "duration": "12.0",
+        "duration": "17.0",
         "name": "blink_perf.layout/line-layout-repeat-append.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.layout/line-layout.html"
     },
     {
-        "duration": "7.0",
+        "duration": "9.0",
         "name": "blink_perf.layout/long-line-nowrap-collapse.html"
     },
     {
-        "duration": "7.0",
+        "duration": "10.0",
         "name": "blink_perf.layout/long-line-nowrap-spans-collapse.html"
     },
     {
-        "duration": "10.0",
+        "duration": "14.0",
         "name": "blink_perf.layout/long-line-nowrap.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.layout/many-block-children-auto-inline-size.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.layout/many-block-children-fixed-inline-size.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.layout/multicol/deeply-nested-tables.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.layout/multicol/fixed-height-with-spanner-and-nested-tables.html"
     },
     {
-        "duration": "12.0",
+        "duration": "14.0",
         "name": "blink_perf.layout/multicol/lots-of-text-autofill.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.layout/multicol/lots-of-text-balanced-orphans-widows.html"
     },
     {
-        "duration": "12.0",
+        "duration": "14.0",
         "name": "blink_perf.layout/multicol/lots-of-text-balanced.html"
     },
     {
-        "duration": "13.0",
+        "duration": "14.0",
         "name": "blink_perf.layout/multicol/tall-content-short-columns-realistic.html"
     },
     {
-        "duration": "12.0",
+        "duration": "14.0",
         "name": "blink_perf.layout/multicol/tall-content-short-columns.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.layout/nested-blocks-with-percent-height-and-max-height.html"
     },
     {
-        "duration": "13.0",
+        "duration": "16.0",
         "name": "blink_perf.layout/nested-grid.html"
     },
     {
-        "duration": "45.0",
+        "duration": "15.0",
         "name": "blink_perf.layout/nested-percent-height-tables.html"
     },
     {
-        "duration": "84.0",
+        "duration": "99.0",
         "name": "blink_perf.layout/subtree-detaching.html"
     },
     {
-        "duration": "8.0",
+        "duration": "13.0",
         "name": "blink_perf.layout/vertical-japanese-kokoro-insert.html"
     },
     {
-        "duration": "9.0",
+        "duration": "19.0",
         "name": "blink_perf.layout/word-break-break-all.html"
     },
     {
-        "duration": "9.0",
+        "duration": "19.0",
         "name": "blink_perf.layout/word-break-break-word.html"
     },
     {
-        "duration": "8.0",
+        "duration": "20.0",
         "name": "blink_perf.layout/word-wrap-break-word.html"
     },
     {
-        "duration": "19.0",
+        "duration": "23.0",
         "name": "blink_perf.owp_storage/blob-perf-files.html"
     },
     {
-        "duration": "15.0",
+        "duration": "20.0",
         "name": "blink_perf.owp_storage/blob-perf-ipc.html"
     },
     {
-        "duration": "15.0",
+        "duration": "20.0",
         "name": "blink_perf.owp_storage/blob-perf-shm.html"
     },
     {
-        "duration": "15.0",
+        "duration": "18.0",
         "name": "blink_perf.owp_storage/blob-perf-tiny.html"
     },
     {
-        "duration": "16.0",
+        "duration": "18.0",
         "name": "blink_perf.owp_storage/idb-load-docs.html"
     },
     {
-        "duration": "20.0",
+        "duration": "26.0",
         "name": "blink_perf.paint/appending-text.html"
     },
     {
-        "duration": "26.0",
+        "duration": "37.0",
         "name": "blink_perf.paint/color-changes.html"
     },
     {
-        "duration": "18.0",
+        "duration": "26.0",
         "name": "blink_perf.paint/complex-content-slow-scroll.html"
     },
     {
-        "duration": "17.0",
+        "duration": "25.0",
         "name": "blink_perf.paint/complex-iframe-filtered.html"
     },
     {
-        "duration": "49.0",
+        "duration": "64.0",
         "name": "blink_perf.paint/contain-update-layer-tree.html"
     },
     {
-        "duration": "19.0",
+        "duration": "29.0",
         "name": "blink_perf.paint/containment-resize.html"
     },
     {
-        "duration": "17.0",
+        "duration": "25.0",
         "name": "blink_perf.paint/fixed-and-many-layers-scroll.html"
     },
     {
-        "duration": "20.0",
+        "duration": "30.0",
         "name": "blink_perf.paint/large-table-background-change-with-invisible-collapsed-borders.html"
     },
     {
-        "duration": "17.0",
+        "duration": "22.0",
         "name": "blink_perf.paint/large-table-background-change-with-visible-collapsed-borders.html"
     },
     {
-        "duration": "21.0",
+        "duration": "31.0",
         "name": "blink_perf.paint/large-table-background-change-with-zero-width-collapsed-borders.html"
     },
     {
-        "duration": "18.0",
+        "duration": "24.0",
         "name": "blink_perf.paint/large-table-collapsed-border-change-with-backgrounds.html"
     },
     {
-        "duration": "21.0",
+        "duration": "30.0",
         "name": "blink_perf.paint/large-table-collapsed-border-change-with-text.html"
     },
     {
-        "duration": "16.0",
+        "duration": "21.0",
         "name": "blink_perf.paint/large-table-collapsed-border-change.html"
     },
     {
-        "duration": "20.0",
+        "duration": "25.0",
         "name": "blink_perf.paint/large-table-repaint.html"
     },
     {
-        "duration": "16.0",
+        "duration": "26.0",
         "name": "blink_perf.paint/move-text-with-mask.html"
     },
     {
-        "duration": "18.0",
+        "duration": "22.0",
         "name": "blink_perf.paint/paint-offset-changes.html"
     },
     {
-        "duration": "22.0",
-        "name": "blink_perf.paint/select-all-words.html"
-    },
-    {
-        "duration": "31.0",
+        "duration": "35.0",
         "name": "blink_perf.paint/transform-changes.html"
     },
     {
-        "duration": "18.0",
+        "duration": "22.0",
         "name": "blink_perf.parser/css-parser-yui.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.parser/html-parser-threaded.html"
     },
     {
-        "duration": "22.0",
+        "duration": "30.0",
         "name": "blink_perf.parser/html-parser.html"
     },
     {
-        "duration": "83.0",
+        "duration": "108.0",
         "name": "blink_perf.parser/html5-full-render.html"
     },
     {
-        "duration": "12.0",
+        "duration": "14.0",
         "name": "blink_perf.parser/iframe-append-remove.html"
     },
     {
-        "duration": "13.0",
+        "duration": "16.0",
         "name": "blink_perf.parser/innerHTML-setter-siblings.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.parser/innerHTML-setter.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.parser/query-selector-all-attribute-complex.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.parser/query-selector-all-attribute.html"
     },
     {
-        "duration": "13.0",
-        "name": "blink_perf.parser/query-selector-all-class-deep.html"
-    },
-    {
-        "duration": "13.0",
+        "duration": "21.0",
         "name": "blink_perf.parser/query-selector-all-class-first.html"
     },
     {
-        "duration": "13.0",
+        "duration": "16.0",
         "name": "blink_perf.parser/query-selector-all-class-last.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.parser/query-selector-all-class.html"
     },
     {
-        "duration": "12.0",
-        "name": "blink_perf.parser/query-selector-all-deep.html"
-    },
-    {
-        "duration": "13.0",
+        "duration": "20.0",
         "name": "blink_perf.parser/query-selector-all-first.html"
     },
     {
-        "duration": "13.0",
-        "name": "blink_perf.parser/query-selector-all-id-deep.html"
-    },
-    {
-        "duration": "13.0",
+        "duration": "19.0",
         "name": "blink_perf.parser/query-selector-all-id-first.html"
     },
     {
-        "duration": "14.0",
+        "duration": "16.0",
         "name": "blink_perf.parser/query-selector-all-id-last.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.parser/query-selector-all-last.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.parser/query-selector-deep.html"
     },
     {
-        "duration": "12.0",
+        "duration": "16.0",
         "name": "blink_perf.parser/query-selector-first.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.parser/query-selector-id-deep.html"
     },
     {
-        "duration": "13.0",
+        "duration": "16.0",
         "name": "blink_perf.parser/query-selector-id-last.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.parser/query-selector-last.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.parser/simple-url.html"
     },
     {
-        "duration": "13.0",
+        "duration": "16.0",
         "name": "blink_perf.parser/textarea-parsing.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.parser/tiny-innerHTML.html"
     },
     {
-        "duration": "14.0",
+        "duration": "17.0",
         "name": "blink_perf.parser/url-parser.html"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "blink_perf.parser/xml-parser.html"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "blink_perf.shadow_dom/declarative-api.html"
     },
     {
-        "duration": "6.0",
+        "duration": "9.0",
         "name": "blink_perf.shadow_dom/imperative-api-appendchild.html"
     },
     {
-        "duration": "7.0",
+        "duration": "8.0",
         "name": "blink_perf.shadow_dom/imperative-api-assign.html"
     },
     {
-        "duration": "6.0",
+        "duration": "10.0",
         "name": "blink_perf.shadow_dom/imperative-api-assigned-elements.html"
     },
     {
-        "duration": "6.0",
+        "duration": "9.0",
         "name": "blink_perf.shadow_dom/imperative-api-assigned-slot.html"
     },
     {
-        "duration": "7.0",
+        "duration": "10.0",
         "name": "blink_perf.shadow_dom/imperative-api-custom-detail-summary-large.html"
     },
     {
-        "duration": "6.0",
+        "duration": "9.0",
         "name": "blink_perf.shadow_dom/imperative-api-custom-detail-summary.html"
     },
     {
-        "duration": "7.0",
+        "duration": "9.0",
         "name": "blink_perf.shadow_dom/imperative-api-detail-summary-large.html"
     },
     {
-        "duration": "6.0",
+        "duration": "9.0",
         "name": "blink_perf.shadow_dom/imperative-api-detail-summary.html"
     },
     {
-        "duration": "6.0",
+        "duration": "9.0",
         "name": "blink_perf.shadow_dom/imperative-api-insertbefore.html"
     },
     {
-        "duration": "6.0",
+        "duration": "9.0",
         "name": "blink_perf.shadow_dom/imperative-api.html"
     },
     {
-        "duration": "8.0",
+        "duration": "11.0",
         "name": "blink_perf.shadow_dom/shadow-style-share-attr-selectors.html"
     },
     {
-        "duration": "7.0",
+        "duration": "11.0",
         "name": "blink_perf.shadow_dom/shadow-style-share-media-query.html"
     },
     {
-        "duration": "7.0",
+        "duration": "10.0",
         "name": "blink_perf.shadow_dom/shadow-style-share-with-distribution.html"
     },
     {
-        "duration": "6.0",
+        "duration": "8.0",
         "name": "blink_perf.shadow_dom/shadow-style-share.html"
     },
     {
-        "duration": "7.0",
+        "duration": "9.0",
         "name": "blink_perf.shadow_dom/style-sheet-insert.html"
     },
     {
-        "duration": "7.0",
+        "duration": "9.0",
         "name": "blink_perf.shadow_dom/v0-changing-classname-with-shadow-dom.html"
     },
     {
-        "duration": "8.0",
+        "duration": "12.0",
         "name": "blink_perf.shadow_dom/v0-changing-classname-without-shadow-dom.html"
     },
     {
-        "duration": "10.0",
+        "duration": "16.0",
         "name": "blink_perf.shadow_dom/v0-changing-select-with-shadow-dom.html"
     },
     {
-        "duration": "12.0",
+        "duration": "18.0",
         "name": "blink_perf.shadow_dom/v0-changing-select-without-shadow-dom.html"
     },
     {
-        "duration": "7.0",
+        "duration": "10.0",
         "name": "blink_perf.shadow_dom/v0-content-reprojection.html"
     },
     {
-        "duration": "6.0",
+        "duration": "9.0",
         "name": "blink_perf.shadow_dom/v0-large-distribution-without-layout.html"
     },
     {
-        "duration": "6.0",
+        "duration": "8.0",
         "name": "blink_perf.shadow_dom/v0-multiple-insertion-points.html"
     },
     {
-        "duration": "7.0",
+        "duration": "10.0",
         "name": "blink_perf.shadow_dom/v0-shadow-reprojection.html"
     },
     {
-        "duration": "7.0",
+        "duration": "9.0",
         "name": "blink_perf.shadow_dom/v0-small-distribution-with-layout.html"
     },
     {
-        "duration": "15.0",
+        "duration": "21.0",
         "name": "blink_perf.shadow_dom/v1-distribution-disconnected-and-reconnected.html"
     },
     {
-        "duration": "7.0",
+        "duration": "9.0",
         "name": "blink_perf.shadow_dom/v1-distribution.html"
     },
     {
-        "duration": "6.0",
+        "duration": "9.0",
         "name": "blink_perf.shadow_dom/v1-host-child-append.html"
     },
     {
-        "duration": "14.0",
+        "duration": "22.0",
         "name": "blink_perf.shadow_dom/v1-large-deep-distribution.html"
     },
     {
-        "duration": "43.0",
+        "duration": "56.0",
         "name": "blink_perf.shadow_dom/v1-large-deep-layout.html"
     },
     {
-        "duration": "7.0",
+        "duration": "9.0",
         "name": "blink_perf.shadow_dom/v1-large-shallow-distribution.html"
     },
     {
-        "duration": "6.0",
+        "duration": "10.0",
         "name": "blink_perf.shadow_dom/v1-large-shallow-layout.html"
     },
     {
-        "duration": "7.0",
+        "duration": "10.0",
         "name": "blink_perf.shadow_dom/v1-mutate-deep-tree-then-re-layout.html"
     },
     {
-        "duration": "6.0",
+        "duration": "11.0",
         "name": "blink_perf.shadow_dom/v1-mutate-deep-tree-then-slot-assigned-nodes.html"
     },
     {
-        "duration": "7.0",
+        "duration": "10.0",
         "name": "blink_perf.shadow_dom/v1-mutate-deep-tree-then-slot-flatten.html"
     },
     {
-        "duration": "7.0",
+        "duration": "9.0",
         "name": "blink_perf.shadow_dom/v1-mutate-shallow-tree-then-re-layout.html"
     },
     {
-        "duration": "6.0",
+        "duration": "8.0",
         "name": "blink_perf.shadow_dom/v1-mutate-shallow-tree-then-slot-assigned-nodes.html"
     },
     {
-        "duration": "7.0",
+        "duration": "9.0",
         "name": "blink_perf.shadow_dom/v1-mutate-shallow-tree-then-slot-flatten.html"
     },
     {
-        "duration": "6.0",
+        "duration": "9.0",
         "name": "blink_perf.shadow_dom/v1-slot-append.html"
     },
     {
-        "duration": "7.0",
+        "duration": "10.0",
         "name": "blink_perf.shadow_dom/v1-small-deep-distribution.html"
     },
     {
-        "duration": "8.0",
+        "duration": "11.0",
         "name": "blink_perf.shadow_dom/v1-small-deep-layout.html"
     },
     {
-        "duration": "6.0",
+        "duration": "8.0",
         "name": "blink_perf.shadow_dom/v1-small-shallow-distribution.html"
     },
     {
-        "duration": "7.0",
+        "duration": "9.0",
         "name": "blink_perf.shadow_dom/v1-small-shallow-layout.html"
     },
     {
-        "duration": "13.0",
+        "duration": "14.0",
         "name": "blink_perf.svg/AzLizardBenjiPark.html"
     },
     {
-        "duration": "9.0",
+        "duration": "11.0",
         "name": "blink_perf.svg/Bamboo.html"
     },
     {
-        "duration": "7.0",
+        "duration": "9.0",
         "name": "blink_perf.svg/Cactus.html"
     },
     {
-        "duration": "7.0",
+        "duration": "9.0",
         "name": "blink_perf.svg/Cowboy.html"
     },
     {
-        "duration": "6.0",
+        "duration": "8.0",
         "name": "blink_perf.svg/CrawFishGanson.html"
     },
     {
-        "duration": "7.0",
+        "duration": "9.0",
         "name": "blink_perf.svg/Debian.html"
     },
     {
-        "duration": "7.0",
+        "duration": "9.0",
         "name": "blink_perf.svg/DropsOnABlade.html"
     },
     {
-        "duration": "7.0",
+        "duration": "9.0",
         "name": "blink_perf.svg/FlowerFromMyGarden.html"
     },
     {
-        "duration": "7.0",
+        "duration": "9.0",
         "name": "blink_perf.svg/FoodLeifLodahl.html"
     },
     {
-        "duration": "7.0",
+        "duration": "9.0",
         "name": "blink_perf.svg/France.html"
     },
     {
-        "duration": "7.0",
+        "duration": "9.0",
         "name": "blink_perf.svg/FrancoBolloGnomeEzechi.html"
     },
     {
-        "duration": "7.0",
+        "duration": "10.0",
         "name": "blink_perf.svg/GearFlowers.html"
     },
     {
-        "duration": "7.0",
+        "duration": "9.0",
         "name": "blink_perf.svg/HarveyRayner.html"
     },
     {
-        "duration": "6.0",
+        "duration": "9.0",
         "name": "blink_perf.svg/HereGear.html"
     },
     {
-        "duration": "10.0",
+        "duration": "13.0",
         "name": "blink_perf.svg/MtSaintHelens.html"
     },
     {
-        "duration": "7.0",
+        "duration": "8.0",
         "name": "blink_perf.svg/Samurai.html"
     },
     {
-        "duration": "89.0",
+        "duration": "81.0",
         "name": "blink_perf.svg/SierpinskiCarpet.html"
     },
     {
-        "duration": "7.0",
+        "duration": "10.0",
         "name": "blink_perf.svg/SvgCubics.html"
     },
     {
-        "duration": "8.0",
+        "duration": "10.0",
         "name": "blink_perf.svg/SvgHitTesting.html"
     },
     {
-        "duration": "13.0",
+        "duration": "17.0",
         "name": "blink_perf.svg/SvgNestedUse.html"
     },
     {
-        "duration": "7.0",
+        "duration": "10.0",
         "name": "blink_perf.svg/UnderTheSee.html"
     },
     {
-        "duration": "8.0",
+        "duration": "10.0",
         "name": "blink_perf.svg/WorldIso.html"
     },
     {
-        "duration": "9.0",
+        "duration": "13.0",
         "name": "blink_perf.svg/Worldcup.html"
     },
     {
-        "duration": "41.0",
+        "duration": "44.0",
         "name": "dromaeo/http://dromaeo.com?dom-attr"
     },
     {
-        "duration": "37.0",
+        "duration": "40.0",
         "name": "dromaeo/http://dromaeo.com?dom-modify"
     },
     {
-        "duration": "53.0",
+        "duration": "56.0",
         "name": "dromaeo/http://dromaeo.com?dom-query"
     },
     {
-        "duration": "33.0",
+        "duration": "36.0",
         "name": "dromaeo/http://dromaeo.com?dom-traverse"
     },
     {
-        "duration": "10.0",
+        "duration": "13.0",
         "name": "dummy_benchmark.noisy_benchmark_1/dummy_page.html"
     },
     {
-        "duration": "10.0",
+        "duration": "14.0",
         "name": "dummy_benchmark.stable_benchmark_1/dummy_page.html"
     },
     {
-        "duration": "283.0",
+        "duration": "275.0",
         "name": "jetstream/http://browserbench.org/JetStream/"
     },
     {
-        "duration": "59.0",
+        "duration": "64.0",
         "name": "kraken/http://krakenbenchmark.mozilla.org/kraken-1.1/driver.html"
     },
     {
@@ -1432,23 +1408,23 @@
         "name": "loading.mobile/58Pic"
     },
     {
-        "duration": "45.0",
+        "duration": "66.0",
         "name": "loading.mobile/58Pic_3g"
     },
     {
-        "duration": "15.0",
+        "duration": "16.0",
         "name": "loading.mobile/Amazon"
     },
     {
-        "duration": "70.0",
+        "duration": "76.0",
         "name": "loading.mobile/Amazon_3g"
     },
     {
-        "duration": "15.0",
+        "duration": "17.0",
         "name": "loading.mobile/BOLNoticias"
     },
     {
-        "duration": "97.0",
+        "duration": "84.0",
         "name": "loading.mobile/BOLNoticias_3g"
     },
     {
@@ -1456,19 +1432,19 @@
         "name": "loading.mobile/Baidu"
     },
     {
-        "duration": "81.0",
+        "duration": "60.0",
         "name": "loading.mobile/Baidu_3g"
     },
     {
-        "duration": "14.0",
+        "duration": "16.0",
         "name": "loading.mobile/Bradesco"
     },
     {
-        "duration": "15.0",
+        "duration": "16.0",
         "name": "loading.mobile/Dailymotion"
     },
     {
-        "duration": "15.0",
+        "duration": "17.0",
         "name": "loading.mobile/Dawn"
     },
     {
@@ -1476,11 +1452,11 @@
         "name": "loading.mobile/DevOpera_cold"
     },
     {
-        "duration": "47.0",
+        "duration": "66.0",
         "name": "loading.mobile/DevOpera_cold_3g"
     },
     {
-        "duration": "20.0",
+        "duration": "19.0",
         "name": "loading.mobile/DevOpera_hot"
     },
     {
@@ -1492,27 +1468,27 @@
         "name": "loading.mobile/DevOpera_warm"
     },
     {
-        "duration": "19.0",
+        "duration": "20.0",
         "name": "loading.mobile/DevOpera_warm_3g"
     },
     {
-        "duration": "15.0",
+        "duration": "16.0",
         "name": "loading.mobile/Dramaq"
     },
     {
-        "duration": "131.0",
+        "duration": "101.0",
         "name": "loading.mobile/Dramaq_3g"
     },
     {
-        "duration": "13.0",
+        "duration": "14.0",
         "name": "loading.mobile/EnquiryIndianRail"
     },
     {
-        "duration": "35.0",
+        "duration": "60.0",
         "name": "loading.mobile/EnquiryIndianRail_3g"
     },
     {
-        "duration": "14.0",
+        "duration": "17.0",
         "name": "loading.mobile/Facebook"
     },
     {
@@ -1520,35 +1496,35 @@
         "name": "loading.mobile/FlipBoard_cold"
     },
     {
-        "duration": "154.0",
+        "duration": "158.0",
         "name": "loading.mobile/FlipBoard_cold_3g"
     },
     {
-        "duration": "22.0",
+        "duration": "21.0",
         "name": "loading.mobile/FlipBoard_hot"
     },
     {
-        "duration": "32.0",
+        "duration": "33.0",
         "name": "loading.mobile/FlipBoard_hot_3g"
     },
     {
-        "duration": "17.0",
+        "duration": "18.0",
         "name": "loading.mobile/FlipBoard_warm"
     },
     {
-        "duration": "32.0",
+        "duration": "34.0",
         "name": "loading.mobile/FlipBoard_warm_3g"
     },
     {
-        "duration": "16.0",
+        "duration": "17.0",
         "name": "loading.mobile/FlipKart_cold"
     },
     {
-        "duration": "21.0",
+        "duration": "19.0",
         "name": "loading.mobile/FlipKart_hot"
     },
     {
-        "duration": "23.0",
+        "duration": "22.0",
         "name": "loading.mobile/FlipKart_hot_3g"
     },
     {
@@ -1556,107 +1532,107 @@
         "name": "loading.mobile/FlipKart_warm"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "loading.mobile/FranceTVInfo"
     },
     {
-        "duration": "59.0",
+        "duration": "95.0",
         "name": "loading.mobile/FranceTVInfo_3g"
     },
     {
-        "duration": "15.0",
+        "duration": "18.0",
         "name": "loading.mobile/GSShop"
     },
     {
-        "duration": "11.0",
+        "duration": "13.0",
         "name": "loading.mobile/GoogleBrazil"
     },
     {
-        "duration": "72.0",
+        "duration": "58.0",
         "name": "loading.mobile/GoogleBrazil_3g"
     },
     {
-        "duration": "12.0",
+        "duration": "14.0",
         "name": "loading.mobile/GoogleIndia"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "loading.mobile/GoogleIndonesia"
     },
     {
-        "duration": "75.0",
+        "duration": "54.0",
         "name": "loading.mobile/GoogleIndonesia_3g"
     },
     {
-        "duration": "15.0",
+        "duration": "17.0",
         "name": "loading.mobile/GoogleRedirectToGoogleJapan"
     },
     {
-        "duration": "89.0",
+        "duration": "84.0",
         "name": "loading.mobile/GoogleRedirectToGoogleJapan_3g"
     },
     {
-        "duration": "14.0",
+        "duration": "16.0",
         "name": "loading.mobile/Hongkiat"
     },
     {
-        "duration": "97.0",
+        "duration": "154.0",
         "name": "loading.mobile/Hongkiat_3g"
     },
     {
-        "duration": "15.0",
+        "duration": "16.0",
         "name": "loading.mobile/KapanLagi"
     },
     {
-        "duration": "18.0",
+        "duration": "19.0",
         "name": "loading.mobile/Kaskus"
     },
     {
-        "duration": "14.0",
+        "duration": "15.0",
         "name": "loading.mobile/LocalMoxie"
     },
     {
-        "duration": "13.0",
+        "duration": "14.0",
         "name": "loading.mobile/Locanto"
     },
     {
-        "duration": "26.0",
+        "duration": "39.0",
         "name": "loading.mobile/Locanto_3g"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "loading.mobile/OLX"
     },
     {
-        "duration": "72.0",
+        "duration": "143.0",
         "name": "loading.mobile/OLX_3g"
     },
     {
-        "duration": "15.0",
+        "duration": "14.0",
         "name": "loading.mobile/QQNews"
     },
     {
-        "duration": "72.0",
+        "duration": "131.0",
         "name": "loading.mobile/QQNews_3g"
     },
     {
-        "duration": "13.0",
+        "duration": "14.0",
         "name": "loading.mobile/SlideShare"
     },
     {
-        "duration": "81.0",
+        "duration": "116.0",
         "name": "loading.mobile/SlideShare_3g"
     },
     {
-        "duration": "14.0",
+        "duration": "15.0",
         "name": "loading.mobile/Suumo_cold"
     },
     {
-        "duration": "16.0",
+        "duration": "18.0",
         "name": "loading.mobile/Suumo_cold_3g"
     },
     {
-        "duration": "19.0",
+        "duration": "18.0",
         "name": "loading.mobile/Suumo_hot"
     },
     {
@@ -1668,139 +1644,139 @@
         "name": "loading.mobile/Suumo_warm"
     },
     {
-        "duration": "16.0",
+        "duration": "17.0",
         "name": "loading.mobile/Suumo_warm_3g"
     },
     {
-        "duration": "14.0",
+        "duration": "16.0",
         "name": "loading.mobile/Thairath"
     },
     {
-        "duration": "16.0",
+        "duration": "18.0",
         "name": "loading.mobile/TheStar"
     },
     {
-        "duration": "16.0",
+        "duration": "17.0",
         "name": "loading.mobile/TribunNews"
     },
     {
-        "duration": "12.0",
+        "duration": "13.0",
         "name": "loading.mobile/Twitter"
     },
     {
-        "duration": "37.0",
+        "duration": "67.0",
         "name": "loading.mobile/Twitter_3g"
     },
     {
-        "duration": "12.0",
+        "duration": "14.0",
         "name": "loading.mobile/VoiceMemos_cold"
     },
     {
-        "duration": "37.0",
+        "duration": "50.0",
         "name": "loading.mobile/VoiceMemos_cold_3g"
     },
     {
-        "duration": "11.0",
+        "duration": "13.0",
         "name": "loading.mobile/Wikipedia"
     },
     {
-        "duration": "68.0",
+        "duration": "53.0",
         "name": "loading.mobile/Wikipedia_3g"
     },
     {
-        "duration": "14.0",
+        "duration": "16.0",
         "name": "loading.mobile/YahooNews"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "loading.mobile/Youtube"
     },
     {
-        "duration": "19.0",
+        "duration": "17.0",
         "name": "media.mobile/mse.html?media=aac_audio.mp4"
     },
     {
-        "duration": "15.0",
+        "duration": "17.0",
         "name": "media.mobile/mse.html?media=aac_audio.mp4,h264_video.mp4"
     },
     {
-        "duration": "16.0",
+        "duration": "19.0",
         "name": "media.mobile/mse.html?media=aac_audio.mp4,h264_video.mp4&waitForPageLoaded=true"
     },
     {
-        "duration": "15.0",
+        "duration": "21.0",
         "name": "media.mobile/mse.html?media=h264_video.mp4"
     },
     {
-        "duration": "28.0",
+        "duration": "26.0",
         "name": "media.mobile/video.html?src=crowd.ogg&type=audio"
     },
     {
-        "duration": "20.0",
+        "duration": "23.0",
         "name": "media.mobile/video.html?src=crowd1080_vp9.webm"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "media.mobile/video.html?src=crowd1080_vp9.webm&seek"
     },
     {
-        "duration": "20.0",
+        "duration": "24.0",
         "name": "media.mobile/video.html?src=crowd720_vp9.webm"
     },
     {
-        "duration": "26.0",
+        "duration": "29.0",
         "name": "media.mobile/video.html?src=tulip2.m4a&type=audio"
     },
     {
-        "duration": "25.0",
+        "duration": "29.0",
         "name": "media.mobile/video.html?src=tulip2.mp3&type=audio"
     },
     {
-        "duration": "11.0",
+        "duration": "14.0",
         "name": "media.mobile/video.html?src=tulip2.mp3&type=audio&seek"
     },
     {
-        "duration": "29.0",
+        "duration": "31.0",
         "name": "media.mobile/video.html?src=tulip2.mp4"
     },
     {
-        "duration": "29.0",
+        "duration": "30.0",
         "name": "media.mobile/video.html?src=tulip2.mp4&busyjs"
     },
     {
-        "duration": "12.0",
+        "duration": "14.0",
         "name": "media.mobile/video.html?src=tulip2.mp4&seek"
     },
     {
-        "duration": "26.0",
+        "duration": "29.0",
         "name": "media.mobile/video.html?src=tulip2.ogg&type=audio"
     },
     {
-        "duration": "11.0",
+        "duration": "14.0",
         "name": "media.mobile/video.html?src=tulip2.ogg&type=audio&seek"
     },
     {
-        "duration": "31.0",
+        "duration": "33.0",
         "name": "media.mobile/video.html?src=tulip2.vp9.webm"
     },
     {
-        "duration": "21.0",
+        "duration": "24.0",
         "name": "media.mobile/video.html?src=tulip2.vp9.webm&background"
     },
     {
-        "duration": "13.0",
+        "duration": "16.0",
         "name": "media.mobile/video.html?src=tulip2.vp9.webm&seek"
     },
     {
-        "duration": "32.0",
+        "duration": "33.0",
         "name": "media.mobile/video.html?src=tulip2.vp9.webm_WiFi"
     },
     {
-        "duration": "26.0",
+        "duration": "29.0",
         "name": "media.mobile/video.html?src=tulip2.wav&type=audio"
     },
     {
-        "duration": "11.0",
+        "duration": "14.0",
         "name": "media.mobile/video.html?src=tulip2.wav&type=audio&seek"
     },
     {
@@ -1808,7 +1784,7 @@
         "name": "memory.top_10_mobile/after_http_en_m_wikipedia_org_wiki_Science"
     },
     {
-        "duration": "16.0",
+        "duration": "15.0",
         "name": "memory.top_10_mobile/after_http_m_intl_taobao_com_group_purchase_html"
     },
     {
@@ -1844,51 +1820,51 @@
         "name": "memory.top_10_mobile/after_https_www_google_co_uk_hl_en_q_science"
     },
     {
-        "duration": "21.0",
+        "duration": "24.0",
         "name": "memory.top_10_mobile/http_en_m_wikipedia_org_wiki_Science"
     },
     {
-        "duration": "20.0",
+        "duration": "23.0",
         "name": "memory.top_10_mobile/http_m_intl_taobao_com_group_purchase_html"
     },
     {
-        "duration": "21.0",
+        "duration": "22.0",
         "name": "memory.top_10_mobile/http_m_youtube_com_results_q_science"
     },
     {
-        "duration": "20.0",
+        "duration": "23.0",
         "name": "memory.top_10_mobile/http_search_yahoo_com_search__ylt_p_google"
     },
     {
-        "duration": "21.0",
+        "duration": "23.0",
         "name": "memory.top_10_mobile/http_www_amazon_com_gp_aw_s_k_nexus"
     },
     {
-        "duration": "24.0",
+        "duration": "25.0",
         "name": "memory.top_10_mobile/http_www_baidu_com_s_word_google"
     },
     {
-        "duration": "21.0",
+        "duration": "24.0",
         "name": "memory.top_10_mobile/http_yandex_ru_touchsearch_text_science"
     },
     {
-        "duration": "21.0",
+        "duration": "23.0",
         "name": "memory.top_10_mobile/https_m_facebook_com_rihanna"
     },
     {
-        "duration": "21.0",
+        "duration": "23.0",
         "name": "memory.top_10_mobile/https_mobile_twitter_com_justinbieber_skip_interstitial_true"
     },
     {
-        "duration": "22.0",
+        "duration": "24.0",
         "name": "memory.top_10_mobile/https_www_google_co_uk_hl_en_q_science"
     },
     {
-        "duration": "60.0",
+        "duration": "61.0",
         "name": "octane/http://chromium.github.io/octane/index.html?auto=1"
     },
     {
-        "duration": "66.0",
+        "duration": "69.0",
         "name": "power.typical_10_mobile/http://de.m.wikipedia.org/wiki/K%C3%B6lner_Dom"
     },
     {
@@ -1896,123 +1872,123 @@
         "name": "power.typical_10_mobile/http://m.chiebukuro.yahoo.co.jp/detail/q10136829180"
     },
     {
-        "duration": "60.0",
+        "duration": "64.0",
         "name": "power.typical_10_mobile/http://m.ebay.com/itm/351157205404"
     },
     {
-        "duration": "69.0",
+        "duration": "68.0",
         "name": "power.typical_10_mobile/http://m.facebook.com/barackobama"
     },
     {
-        "duration": "66.0",
+        "duration": "68.0",
         "name": "power.typical_10_mobile/http://m.huffpost.com/us/entry/6004486"
     },
     {
-        "duration": "64.0",
+        "duration": "68.0",
         "name": "power.typical_10_mobile/http://m.ynet.co.il"
     },
     {
-        "duration": "65.0",
+        "duration": "69.0",
         "name": "power.typical_10_mobile/http://siriuslymeg.tumblr.com/"
     },
     {
-        "duration": "62.0",
+        "duration": "64.0",
         "name": "power.typical_10_mobile/http://wapbaike.baidu.com/"
     },
     {
-        "duration": "61.0",
+        "duration": "64.0",
         "name": "power.typical_10_mobile/http://www.cnn.com/2014/03/31/showbiz/tv/himym-finale/index.html"
     },
     {
-        "duration": "66.0",
+        "duration": "70.0",
         "name": "power.typical_10_mobile/http://www.rg.ru/2014/10/21/cska-site.html"
     },
     {
-        "duration": "66.0",
+        "duration": "67.0",
         "name": "power.typical_10_mobile/https://en.wikipedia.org/wiki/File:Rotating_earth_(large).gif"
     },
     {
-        "duration": "18.0",
+        "duration": "20.0",
         "name": "rasterize_and_record_micro.partial_invalidation/800_relpos_divs.html"
     },
     {
-        "duration": "27.0",
+        "duration": "32.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/amazon.html"
     },
     {
-        "duration": "13.0",
+        "duration": "16.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/blogger.html"
     },
     {
-        "duration": "24.0",
+        "duration": "27.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/booking.html"
     },
     {
-        "duration": "17.0",
+        "duration": "19.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/cnn.html"
     },
     {
-        "duration": "12.0",
+        "duration": "16.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/ebay.html"
     },
     {
-        "duration": "27.0",
+        "duration": "32.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/espn.html"
     },
     {
-        "duration": "22.0",
+        "duration": "25.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/facebook.html"
     },
     {
-        "duration": "38.0",
+        "duration": "41.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/gmail.html"
     },
     {
-        "duration": "32.0",
+        "duration": "33.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/google.html"
     },
     {
-        "duration": "29.0",
+        "duration": "31.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/googlecalendar.html"
     },
     {
-        "duration": "23.0",
+        "duration": "25.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/googledocs.html"
     },
     {
-        "duration": "26.0",
+        "duration": "29.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/googleimagesearch.html"
     },
     {
-        "duration": "23.0",
+        "duration": "27.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/googleplus.html"
     },
     {
-        "duration": "22.0",
+        "duration": "24.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/linkedin.html"
     },
     {
-        "duration": "11.0",
+        "duration": "14.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/pinterest.html"
     },
     {
-        "duration": "18.0",
+        "duration": "21.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/techcrunch.html"
     },
     {
-        "duration": "32.0",
+        "duration": "34.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/twitter.html"
     },
     {
-        "duration": "17.0",
+        "duration": "18.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/weather.html"
     },
     {
-        "duration": "15.0",
+        "duration": "17.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/wordpress.html"
     },
     {
-        "duration": "21.0",
+        "duration": "23.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/yahooanswers.html"
     },
     {
@@ -2020,19 +1996,19 @@
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/yahoogames.html"
     },
     {
-        "duration": "89.0",
+        "duration": "91.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/yahoosports.html"
     },
     {
-        "duration": "35.0",
+        "duration": "37.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/youtube.html"
     },
     {
-        "duration": "26.0",
+        "duration": "29.0",
         "name": "rendering.mobile/accu_weather_2018"
     },
     {
-        "duration": "28.0",
+        "duration": "26.0",
         "name": "rendering.mobile/accu_weather_mobile_pinch_2018"
     },
     {
@@ -2040,39 +2016,39 @@
         "name": "rendering.mobile/amazon_2018"
     },
     {
-        "duration": "23.0",
+        "duration": "24.0",
         "name": "rendering.mobile/amazon_mobile_2018"
     },
     {
-        "duration": "22.0",
+        "duration": "23.0",
         "name": "rendering.mobile/analog_clock_svg"
     },
     {
-        "duration": "24.0",
+        "duration": "27.0",
         "name": "rendering.mobile/androidpolice_mobile_2018"
     },
     {
-        "duration": "20.0",
+        "duration": "19.0",
         "name": "rendering.mobile/animometer_webgl"
     },
     {
-        "duration": "17.0",
+        "duration": "18.0",
         "name": "rendering.mobile/animometer_webgl_attrib_arrays"
     },
     {
-        "duration": "18.0",
+        "duration": "21.0",
         "name": "rendering.mobile/animometer_webgl_multi_draw"
     },
     {
-        "duration": "26.0",
+        "duration": "23.0",
         "name": "rendering.mobile/aquarium"
     },
     {
-        "duration": "23.0",
+        "duration": "25.0",
         "name": "rendering.mobile/background_color_animation"
     },
     {
-        "duration": "22.0",
+        "duration": "24.0",
         "name": "rendering.mobile/background_color_animation_with_gradient"
     },
     {
@@ -2080,39 +2056,39 @@
         "name": "rendering.mobile/baidu_mobile_2018"
     },
     {
-        "duration": "21.0",
+        "duration": "24.0",
         "name": "rendering.mobile/balls_css_key_frame_animations"
     },
     {
-        "duration": "21.0",
+        "duration": "25.0",
         "name": "rendering.mobile/balls_css_transition_2_properties"
     },
     {
-        "duration": "21.0",
+        "duration": "23.0",
         "name": "rendering.mobile/balls_css_transition_40_properties"
     },
     {
-        "duration": "21.0",
+        "duration": "23.0",
         "name": "rendering.mobile/balls_css_transition_all_properties"
     },
     {
-        "duration": "20.0",
+        "duration": "23.0",
         "name": "rendering.mobile/balls_javascript_canvas"
     },
     {
-        "duration": "20.0",
+        "duration": "23.0",
         "name": "rendering.mobile/balls_javascript_css"
     },
     {
-        "duration": "23.0",
+        "duration": "25.0",
         "name": "rendering.mobile/balls_svg_animations"
     },
     {
-        "duration": "23.0",
+        "duration": "24.0",
         "name": "rendering.mobile/basic_stream"
     },
     {
-        "duration": "18.0",
+        "duration": "31.0",
         "name": "rendering.mobile/bing_mobile_2018"
     },
     {
@@ -2120,107 +2096,107 @@
         "name": "rendering.mobile/blob"
     },
     {
-        "duration": "16.0",
+        "duration": "18.0",
         "name": "rendering.mobile/blogspot_2018"
     },
     {
-        "duration": "15.0",
+        "duration": "14.0",
         "name": "rendering.mobile/blogspot_mobile_2018"
     },
     {
-        "duration": "16.0",
+        "duration": "18.0",
         "name": "rendering.mobile/blur_rotating_background"
     },
     {
-        "duration": "18.0",
+        "duration": "19.0",
         "name": "rendering.mobile/boingboing_mobile_2018"
     },
     {
-        "duration": "18.0",
+        "duration": "19.0",
         "name": "rendering.mobile/booking.com_2018"
     },
     {
-        "duration": "14.0",
+        "duration": "13.0",
         "name": "rendering.mobile/booking.com_mobile_2018"
     },
     {
-        "duration": "15.0",
+        "duration": "19.0",
         "name": "rendering.mobile/bouncing_balls_15"
     },
     {
-        "duration": "16.0",
+        "duration": "19.0",
         "name": "rendering.mobile/bouncing_balls_shadow"
     },
     {
-        "duration": "15.0",
+        "duration": "18.0",
         "name": "rendering.mobile/bouncing_clipped_rectangles"
     },
     {
-        "duration": "15.0",
+        "duration": "18.0",
         "name": "rendering.mobile/bouncing_gradient_circles"
     },
     {
-        "duration": "14.0",
+        "duration": "17.0",
         "name": "rendering.mobile/bouncing_png_images"
     },
     {
-        "duration": "17.0",
+        "duration": "19.0",
         "name": "rendering.mobile/bouncing_svg_images"
     },
     {
-        "duration": "21.0",
+        "duration": "22.0",
         "name": "rendering.mobile/camera_to_webgl"
     },
     {
-        "duration": "18.0",
+        "duration": "20.0",
         "name": "rendering.mobile/canvas_05000_pixels_per_second"
     },
     {
-        "duration": "19.0",
+        "duration": "20.0",
         "name": "rendering.mobile/canvas_10000_pixels_per_second"
     },
     {
-        "duration": "18.0",
+        "duration": "20.0",
         "name": "rendering.mobile/canvas_20000_pixels_per_second"
     },
     {
-        "duration": "17.0",
+        "duration": "20.0",
         "name": "rendering.mobile/canvas_40000_pixels_per_second"
     },
     {
-        "duration": "15.0",
+        "duration": "18.0",
         "name": "rendering.mobile/canvas_60000_pixels_per_second"
     },
     {
-        "duration": "14.0",
+        "duration": "17.0",
         "name": "rendering.mobile/canvas_75000_pixels_per_second"
     },
     {
-        "duration": "14.0",
+        "duration": "17.0",
         "name": "rendering.mobile/canvas_90000_pixels_per_second"
     },
     {
-        "duration": "15.0",
+        "duration": "18.0",
         "name": "rendering.mobile/canvas_animation_no_clear"
     },
     {
-        "duration": "15.0",
+        "duration": "18.0",
         "name": "rendering.mobile/canvas_arcs"
     },
     {
-        "duration": "15.0",
+        "duration": "18.0",
         "name": "rendering.mobile/canvas_font_cycler"
     },
     {
-        "duration": "15.0",
+        "duration": "17.0",
         "name": "rendering.mobile/canvas_lines"
     },
     {
-        "duration": "15.0",
+        "duration": "19.0",
         "name": "rendering.mobile/canvas_to_blob"
     },
     {
-        "duration": "22.0",
+        "duration": "23.0",
         "name": "rendering.mobile/capitolvolkswagen_mobile_2018"
     },
     {
@@ -2228,11 +2204,11 @@
         "name": "rendering.mobile/card_expansion"
     },
     {
-        "duration": "17.0",
+        "duration": "18.0",
         "name": "rendering.mobile/card_expansion_animated"
     },
     {
-        "duration": "18.0",
+        "duration": "19.0",
         "name": "rendering.mobile/card_expansion_images_text"
     },
     {
@@ -2244,27 +2220,27 @@
         "name": "rendering.mobile/cats_unscaled"
     },
     {
-        "duration": "12.0",
+        "duration": "14.0",
         "name": "rendering.mobile/cats_viewport_width"
     },
     {
-        "duration": "24.0",
+        "duration": "26.0",
         "name": "rendering.mobile/cc_poster_circle"
     },
     {
-        "duration": "23.0",
+        "duration": "24.0",
         "name": "rendering.mobile/cc_scroll_text_only"
     },
     {
-        "duration": "18.0",
+        "duration": "19.0",
         "name": "rendering.mobile/chip_tune"
     },
     {
-        "duration": "17.0",
+        "duration": "18.0",
         "name": "rendering.mobile/cnn_2018"
     },
     {
-        "duration": "19.0",
+        "duration": "20.0",
         "name": "rendering.mobile/cnn_article_mobile_2018"
     },
     {
@@ -2272,175 +2248,175 @@
         "name": "rendering.mobile/cnn_mobile_2018"
     },
     {
-        "duration": "21.0",
+        "duration": "22.0",
         "name": "rendering.mobile/cnn_mobile_pinch_2018"
     },
     {
-        "duration": "19.0",
+        "duration": "18.0",
         "name": "rendering.mobile/cnn_pathological_2018"
     },
     {
-        "duration": "20.0",
+        "duration": "24.0",
         "name": "rendering.mobile/compositor_heavy_animation"
     },
     {
-        "duration": "17.0",
+        "duration": "18.0",
         "name": "rendering.mobile/coordinated_animation"
     },
     {
-        "duration": "15.0",
+        "duration": "16.0",
         "name": "rendering.mobile/crafty_mind"
     },
     {
-        "duration": "22.0",
+        "duration": "24.0",
         "name": "rendering.mobile/css_animations_many_keyframes"
     },
     {
-        "duration": "20.0",
+        "duration": "23.0",
         "name": "rendering.mobile/css_animations_simultaneous_inline_style"
     },
     {
-        "duration": "21.0",
+        "duration": "22.0",
         "name": "rendering.mobile/css_animations_simultaneous_new_element"
     },
     {
-        "duration": "21.0",
+        "duration": "22.0",
         "name": "rendering.mobile/css_animations_simultaneous_style_element"
     },
     {
-        "duration": "20.0",
+        "duration": "25.0",
         "name": "rendering.mobile/css_animations_simultaneous_updating_class"
     },
     {
-        "duration": "21.0",
+        "duration": "22.0",
         "name": "rendering.mobile/css_animations_staggered_infinite_iterations"
     },
     {
-        "duration": "22.0",
+        "duration": "24.0",
         "name": "rendering.mobile/css_animations_staggered_inline_style"
     },
     {
-        "duration": "24.0",
+        "duration": "26.0",
         "name": "rendering.mobile/css_animations_staggered_new_element"
     },
     {
-        "duration": "22.0",
+        "duration": "24.0",
         "name": "rendering.mobile/css_animations_staggered_style_element"
     },
     {
-        "duration": "22.0",
+        "duration": "25.0",
         "name": "rendering.mobile/css_animations_staggered_updating_class"
     },
     {
-        "duration": "22.0",
+        "duration": "25.0",
         "name": "rendering.mobile/css_animations_triggered_inline_style"
     },
     {
-        "duration": "24.0",
+        "duration": "26.0",
         "name": "rendering.mobile/css_animations_triggered_new_element"
     },
     {
-        "duration": "22.0",
+        "duration": "24.0",
         "name": "rendering.mobile/css_animations_triggered_style_element"
     },
     {
-        "duration": "23.0",
+        "duration": "25.0",
         "name": "rendering.mobile/css_animations_triggered_updating_class"
     },
     {
-        "duration": "23.0",
+        "duration": "27.0",
         "name": "rendering.mobile/css_opacity_plus_n_layers_0"
     },
     {
-        "duration": "24.0",
+        "duration": "26.0",
         "name": "rendering.mobile/css_opacity_plus_n_layers_75"
     },
     {
-        "duration": "24.0",
+        "duration": "27.0",
         "name": "rendering.mobile/css_opacity_plus_n_layers_99"
     },
     {
-        "duration": "21.0",
+        "duration": "24.0",
         "name": "rendering.mobile/css_transitions_inline_style"
     },
     {
-        "duration": "21.0",
+        "duration": "24.0",
         "name": "rendering.mobile/css_transitions_new_element"
     },
     {
-        "duration": "21.0",
+        "duration": "24.0",
         "name": "rendering.mobile/css_transitions_staggered_inline_style"
     },
     {
-        "duration": "21.0",
+        "duration": "23.0",
         "name": "rendering.mobile/css_transitions_staggered_new_element"
     },
     {
-        "duration": "21.0",
+        "duration": "23.0",
         "name": "rendering.mobile/css_transitions_staggered_style_element"
     },
     {
-        "duration": "21.0",
+        "duration": "25.0",
         "name": "rendering.mobile/css_transitions_staggered_updating_class"
     },
     {
-        "duration": "21.0",
+        "duration": "22.0",
         "name": "rendering.mobile/css_transitions_style_element"
     },
     {
-        "duration": "21.0",
+        "duration": "23.0",
         "name": "rendering.mobile/css_transitions_triggered_inline_style"
     },
     {
-        "duration": "22.0",
+        "duration": "23.0",
         "name": "rendering.mobile/css_transitions_triggered_new_element"
     },
     {
-        "duration": "22.0",
+        "duration": "24.0",
         "name": "rendering.mobile/css_transitions_triggered_style_element"
     },
     {
-        "duration": "21.0",
+        "duration": "24.0",
         "name": "rendering.mobile/css_transitions_triggered_updating_class"
     },
     {
-        "duration": "21.0",
+        "duration": "23.0",
         "name": "rendering.mobile/css_transitions_updating_class"
     },
     {
-        "duration": "21.0",
+        "duration": "23.0",
         "name": "rendering.mobile/css_value_type_color"
     },
     {
-        "duration": "23.0",
+        "duration": "25.0",
         "name": "rendering.mobile/css_value_type_filter"
     },
     {
-        "duration": "21.0",
+        "duration": "24.0",
         "name": "rendering.mobile/css_value_type_length"
     },
     {
-        "duration": "22.0",
+        "duration": "24.0",
         "name": "rendering.mobile/css_value_type_length_complex"
     },
     {
-        "duration": "22.0",
+        "duration": "24.0",
         "name": "rendering.mobile/css_value_type_length_simple"
     },
     {
-        "duration": "21.0",
+        "duration": "23.0",
         "name": "rendering.mobile/css_value_type_path"
     },
     {
-        "duration": "20.0",
+        "duration": "22.0",
         "name": "rendering.mobile/css_value_type_shadow"
     },
     {
-        "duration": "21.0",
+        "duration": "23.0",
         "name": "rendering.mobile/css_value_type_transform_complex"
     },
     {
-        "duration": "21.0",
+        "duration": "23.0",
         "name": "rendering.mobile/css_value_type_transform_simple"
     },
     {
@@ -2448,27 +2424,27 @@
         "name": "rendering.mobile/deviantart_mobile_2018"
     },
     {
-        "duration": "17.0",
+        "duration": "18.0",
         "name": "rendering.mobile/digg_mobile_2018"
     },
     {
-        "duration": "19.0",
+        "duration": "18.0",
         "name": "rendering.mobile/dynamic_cube_map"
     },
     {
-        "duration": "19.0",
+        "duration": "20.0",
         "name": "rendering.mobile/earth"
     },
     {
-        "duration": "18.0",
+        "duration": "19.0",
         "name": "rendering.mobile/ebay_2018"
     },
     {
-        "duration": "15.0",
+        "duration": "16.0",
         "name": "rendering.mobile/ebay_mobile_2018"
     },
     {
-        "duration": "18.0",
+        "duration": "22.0",
         "name": "rendering.mobile/ebay_mobile_pinch_2018"
     },
     {
@@ -2476,35 +2452,35 @@
         "name": "rendering.mobile/ebay_scroll_2018"
     },
     {
-        "duration": "15.0",
+        "duration": "20.0",
         "name": "rendering.mobile/effect_games"
     },
     {
-        "duration": "18.0",
+        "duration": "26.0",
         "name": "rendering.mobile/espn_2018"
     },
     {
-        "duration": "16.0",
+        "duration": "23.0",
         "name": "rendering.mobile/espn_mobile_2018"
     },
     {
-        "duration": "16.0",
+        "duration": "17.0",
         "name": "rendering.mobile/espn_pathological_2018"
     },
     {
-        "duration": "28.0",
+        "duration": "27.0",
         "name": "rendering.mobile/extra_large_texture_uploads"
     },
     {
-        "duration": "30.0",
+        "duration": "17.0",
         "name": "rendering.mobile/facebook_2018"
     },
     {
-        "duration": "28.0",
+        "duration": "25.0",
         "name": "rendering.mobile/facebook_mobile_2018"
     },
     {
-        "duration": "15.0",
+        "duration": "19.0",
         "name": "rendering.mobile/fill_shapes"
     },
     {
@@ -2516,23 +2492,23 @@
         "name": "rendering.mobile/flickr_scroll_2018"
     },
     {
-        "duration": "16.0",
+        "duration": "21.0",
         "name": "rendering.mobile/font_wipe"
     },
     {
-        "duration": "14.0",
+        "duration": "16.0",
         "name": "rendering.mobile/forecast.io_mobile_2018"
     },
     {
-        "duration": "35.0",
+        "duration": "87.0",
         "name": "rendering.mobile/geo_apis"
     },
     {
-        "duration": "29.0",
+        "duration": "23.0",
         "name": "rendering.mobile/gmail_2018"
     },
     {
-        "duration": "14.0",
+        "duration": "17.0",
         "name": "rendering.mobile/google_calendar_2018"
     },
     {
@@ -2540,7 +2516,7 @@
         "name": "rendering.mobile/google_docs_2018"
     },
     {
-        "duration": "25.0",
+        "duration": "20.0",
         "name": "rendering.mobile/google_image_search_2018"
     },
     {
@@ -2548,15 +2524,15 @@
         "name": "rendering.mobile/google_image_search_mobile_2018"
     },
     {
-        "duration": "18.0",
+        "duration": "19.0",
         "name": "rendering.mobile/google_news_ios"
     },
     {
-        "duration": "15.0",
+        "duration": "19.0",
         "name": "rendering.mobile/google_news_mobile_2018"
     },
     {
-        "duration": "20.0",
+        "duration": "22.0",
         "name": "rendering.mobile/google_plus_2018"
     },
     {
@@ -2568,7 +2544,7 @@
         "name": "rendering.mobile/google_search_mobile_pinch_2018"
     },
     {
-        "duration": "16.0",
+        "duration": "17.0",
         "name": "rendering.mobile/google_web_search_2018"
     },
     {
@@ -2576,27 +2552,27 @@
         "name": "rendering.mobile/google_web_search_mobile_2018"
     },
     {
-        "duration": "21.0",
+        "duration": "22.0",
         "name": "rendering.mobile/gsp.ro_mobile_2018"
     },
     {
-        "duration": "23.0",
+        "duration": "22.0",
         "name": "rendering.mobile/guardian_pathological_2018"
     },
     {
-        "duration": "41.0",
+        "duration": "23.0",
         "name": "rendering.mobile/guimark_vector_chart"
     },
     {
-        "duration": "18.0",
+        "duration": "20.0",
         "name": "rendering.mobile/gws_boogie_expansion"
     },
     {
-        "duration": "18.0",
+        "duration": "19.0",
         "name": "rendering.mobile/gws_google_expansion"
     },
     {
-        "duration": "22.0",
+        "duration": "16.0",
         "name": "rendering.mobile/hakim"
     },
     {
@@ -2604,75 +2580,75 @@
         "name": "rendering.mobile/horizontal_vertical_expansion"
     },
     {
-        "duration": "42.0",
+        "duration": "46.0",
         "name": "rendering.mobile/idle_power_animated_gif"
     },
     {
-        "duration": "32.0",
+        "duration": "36.0",
         "name": "rendering.mobile/idle_power_blank"
     },
     {
-        "duration": "36.0",
+        "duration": "38.0",
         "name": "rendering.mobile/idle_power_css_animation"
     },
     {
-        "duration": "36.0",
+        "duration": "38.0",
         "name": "rendering.mobile/idle_power_request_animation_frame"
     },
     {
-        "duration": "105.0",
+        "duration": "109.0",
         "name": "rendering.mobile/idle_power_set_timeout_long"
     },
     {
-        "duration": "36.0",
+        "duration": "38.0",
         "name": "rendering.mobile/idle_power_set_timetout"
     },
     {
-        "duration": "32.0",
+        "duration": "34.0",
         "name": "rendering.mobile/ie_chalkboard"
     },
     {
-        "duration": "43.0",
+        "duration": "24.0",
         "name": "rendering.mobile/ie_pirate_mark"
     },
     {
-        "duration": "23.0",
+        "duration": "26.0",
         "name": "rendering.mobile/infinite_scroll_element_n_layers_0"
     },
     {
-        "duration": "23.0",
+        "duration": "28.0",
         "name": "rendering.mobile/infinite_scroll_element_n_layers_75"
     },
     {
-        "duration": "24.0",
+        "duration": "27.0",
         "name": "rendering.mobile/infinite_scroll_element_n_layers_99"
     },
     {
-        "duration": "23.0",
+        "duration": "26.0",
         "name": "rendering.mobile/infinite_scroll_root_fixed_n_layers_0"
     },
     {
-        "duration": "23.0",
+        "duration": "26.0",
         "name": "rendering.mobile/infinite_scroll_root_fixed_n_layers_75"
     },
     {
-        "duration": "24.0",
+        "duration": "26.0",
         "name": "rendering.mobile/infinite_scroll_root_fixed_n_layers_99"
     },
     {
-        "duration": "23.0",
+        "duration": "27.0",
         "name": "rendering.mobile/infinite_scroll_root_n_layers_0"
     },
     {
-        "duration": "23.0",
+        "duration": "26.0",
         "name": "rendering.mobile/infinite_scroll_root_n_layers_75"
     },
     {
-        "duration": "23.0",
+        "duration": "26.0",
         "name": "rendering.mobile/infinite_scroll_root_n_layers_99"
     },
     {
-        "duration": "21.0",
+        "duration": "23.0",
         "name": "rendering.mobile/infinite_scrolling"
     },
     {
@@ -2680,39 +2656,47 @@
         "name": "rendering.mobile/jarro_doverson"
     },
     {
-        "duration": "28.0",
+        "duration": "17.0",
+        "name": "rendering.mobile/jpeg_decoding_rgb_and_gpu_rasterization"
+    },
+    {
+        "duration": "18.0",
+        "name": "rendering.mobile/jpeg_decoding_yuv_and_gpu_rasterization"
+    },
+    {
+        "duration": "29.0",
         "name": "rendering.mobile/js_full_screen_invalidation"
     },
     {
-        "duration": "24.0",
+        "duration": "27.0",
         "name": "rendering.mobile/js_opacity_plus_n_layers_0"
     },
     {
-        "duration": "24.0",
+        "duration": "26.0",
         "name": "rendering.mobile/js_opacity_plus_n_layers_75"
     },
     {
-        "duration": "25.0",
+        "duration": "27.0",
         "name": "rendering.mobile/js_opacity_plus_n_layers_99"
     },
     {
-        "duration": "25.0",
+        "duration": "29.0",
         "name": "rendering.mobile/js_paint_plus_n_layers_0"
     },
     {
-        "duration": "25.0",
+        "duration": "28.0",
         "name": "rendering.mobile/js_paint_plus_n_layers_75"
     },
     {
-        "duration": "25.0",
+        "duration": "27.0",
         "name": "rendering.mobile/js_paint_plus_n_layers_99"
     },
     {
-        "duration": "25.0",
+        "duration": "26.0",
         "name": "rendering.mobile/js_poster_circle"
     },
     {
-        "duration": "14.0",
+        "duration": "17.0",
         "name": "rendering.mobile/js_scroll_text_only"
     },
     {
@@ -2720,35 +2704,35 @@
         "name": "rendering.mobile/kevs_3d"
     },
     {
-        "duration": "20.0",
+        "duration": "24.0",
         "name": "rendering.mobile/keyframed_animations"
     },
     {
-        "duration": "20.0",
+        "duration": "22.0",
         "name": "rendering.mobile/large_texture_uploads"
     },
     {
-        "duration": "25.0",
+        "duration": "22.0",
         "name": "rendering.mobile/latimes_pathological_2018"
     },
     {
-        "duration": "19.0",
+        "duration": "20.0",
         "name": "rendering.mobile/linkedin_2018"
     },
     {
-        "duration": "40.0",
+        "duration": "41.0",
         "name": "rendering.mobile/linkedin_mobile_2018"
     },
     {
-        "duration": "37.0",
+        "duration": "36.0",
         "name": "rendering.mobile/linkedin_mobile_pinch_2018"
     },
     {
-        "duration": "31.0",
+        "duration": "32.0",
         "name": "rendering.mobile/linkedin_pathological_2018"
     },
     {
-        "duration": "14.0",
+        "duration": "17.0",
         "name": "rendering.mobile/list_animation_simple"
     },
     {
@@ -2756,7 +2740,7 @@
         "name": "rendering.mobile/list_recycle_transform"
     },
     {
-        "duration": "15.0",
+        "duration": "18.0",
         "name": "rendering.mobile/man_in_blue"
     },
     {
@@ -2768,43 +2752,43 @@
         "name": "rendering.mobile/many_planets_deep"
     },
     {
-        "duration": "25.0",
+        "duration": "27.0",
         "name": "rendering.mobile/maps_perf_test"
     },
     {
-        "duration": "16.0",
+        "duration": "17.0",
         "name": "rendering.mobile/mask_transition_animation"
     },
     {
-        "duration": "14.0",
+        "duration": "17.0",
         "name": "rendering.mobile/masonry"
     },
     {
-        "duration": "21.0",
+        "duration": "23.0",
         "name": "rendering.mobile/medium_texture_uploads"
     },
     {
-        "duration": "15.0",
+        "duration": "17.0",
         "name": "rendering.mobile/megi_dish"
     },
     {
-        "duration": "18.0",
+        "duration": "19.0",
         "name": "rendering.mobile/microsoft_asteroid_belt"
     },
     {
-        "duration": "16.0",
+        "duration": "17.0",
         "name": "rendering.mobile/microsoft_fish_ie_tank"
     },
     {
-        "duration": "21.0",
+        "duration": "24.0",
         "name": "rendering.mobile/microsoft_performance"
     },
     {
-        "duration": "16.0",
+        "duration": "17.0",
         "name": "rendering.mobile/microsoft_snow"
     },
     {
-        "duration": "16.0",
+        "duration": "18.0",
         "name": "rendering.mobile/microsoft_speed_reading"
     },
     {
@@ -2816,51 +2800,51 @@
         "name": "rendering.mobile/microsoft_video_city"
     },
     {
-        "duration": "15.0",
+        "duration": "18.0",
         "name": "rendering.mobile/microsoft_worker_fountains"
     },
     {
-        "duration": "16.0",
+        "duration": "17.0",
         "name": "rendering.mobile/mix_10k"
     },
     {
-        "duration": "20.0",
+        "duration": "23.0",
         "name": "rendering.mobile/mix_blend_mode_animation_difference"
     },
     {
-        "duration": "19.0",
+        "duration": "22.0",
         "name": "rendering.mobile/mix_blend_mode_animation_hue"
     },
     {
-        "duration": "21.0",
+        "duration": "24.0",
         "name": "rendering.mobile/mix_blend_mode_animation_propagating_isolation"
     },
     {
-        "duration": "19.0",
+        "duration": "23.0",
         "name": "rendering.mobile/mix_blend_mode_animation_screen"
     },
     {
-        "duration": "23.0",
+        "duration": "25.0",
         "name": "rendering.mobile/mlb_mobile_2018"
     },
     {
-        "duration": "15.0",
+        "duration": "17.0",
         "name": "rendering.mobile/mobile_news_sandbox"
     },
     {
-        "duration": "51.0",
+        "duration": "22.0",
         "name": "rendering.mobile/motion_mark_canvas_fill_shapes"
     },
     {
-        "duration": "26.0",
+        "duration": "21.0",
         "name": "rendering.mobile/motion_mark_canvas_stroke_shapes"
     },
     {
-        "duration": "19.0",
+        "duration": "21.0",
         "name": "rendering.mobile/motionmark_anim_design_15"
     },
     {
-        "duration": "20.0",
+        "duration": "21.0",
         "name": "rendering.mobile/motionmark_anim_focus_25"
     },
     {
@@ -2868,11 +2852,11 @@
         "name": "rendering.mobile/motionmark_anim_images_50"
     },
     {
-        "duration": "20.0",
+        "duration": "21.0",
         "name": "rendering.mobile/motionmark_anim_leaves_250"
     },
     {
-        "duration": "20.0",
+        "duration": "22.0",
         "name": "rendering.mobile/motionmark_anim_multiply_175"
     },
     {
@@ -2880,31 +2864,31 @@
         "name": "rendering.mobile/motionmark_anim_suits_125"
     },
     {
-        "duration": "20.0",
+        "duration": "22.0",
         "name": "rendering.mobile/motionmark_html_composited_transforms_125"
     },
     {
-        "duration": "20.0",
+        "duration": "21.0",
         "name": "rendering.mobile/motionmark_html_css_bouncing_blend_circles_25"
     },
     {
-        "duration": "20.0",
+        "duration": "21.0",
         "name": "rendering.mobile/motionmark_html_css_bouncing_circles_250"
     },
     {
-        "duration": "20.0",
+        "duration": "21.0",
         "name": "rendering.mobile/motionmark_html_css_bouncing_clipped_rects_100"
     },
     {
-        "duration": "20.0",
+        "duration": "21.0",
         "name": "rendering.mobile/motionmark_html_css_bouncing_filter_circles_15"
     },
     {
-        "duration": "20.0",
+        "duration": "21.0",
         "name": "rendering.mobile/motionmark_html_css_bouncing_gradient_circles_250"
     },
     {
-        "duration": "20.0",
+        "duration": "22.0",
         "name": "rendering.mobile/motionmark_html_css_bouncing_svg_images_50"
     },
     {
@@ -2916,11 +2900,11 @@
         "name": "rendering.mobile/motionmark_html_dom_particles_svg_masks_25"
     },
     {
-        "duration": "20.0",
+        "duration": "21.0",
         "name": "rendering.mobile/motionmark_html_focus_20_15"
     },
     {
-        "duration": "21.0",
+        "duration": "22.0",
         "name": "rendering.mobile/motionmark_html_leaves_20_50"
     },
     {
@@ -2928,15 +2912,15 @@
         "name": "rendering.mobile/motionmark_svg_bouncing_circles_250"
     },
     {
-        "duration": "21.0",
+        "duration": "20.0",
         "name": "rendering.mobile/motionmark_svg_bouncing_clipped_rects_100"
     },
     {
-        "duration": "21.0",
+        "duration": "22.0",
         "name": "rendering.mobile/motionmark_svg_bouncing_gradient_circles_200"
     },
     {
-        "duration": "20.0",
+        "duration": "22.0",
         "name": "rendering.mobile/motionmark_svg_bouncing_png_images_200"
     },
     {
@@ -2944,27 +2928,27 @@
         "name": "rendering.mobile/motionmark_svg_bouncing_svg_images_50"
     },
     {
-        "duration": "26.0",
+        "duration": "27.0",
         "name": "rendering.mobile/new_tilings"
     },
     {
-        "duration": "19.0",
+        "duration": "21.0",
         "name": "rendering.mobile/no_op_raf"
     },
     {
-        "duration": "18.0",
+        "duration": "21.0",
         "name": "rendering.mobile/no_op_scroll"
     },
     {
-        "duration": "16.0",
+        "duration": "19.0",
         "name": "rendering.mobile/no_op_settimeout"
     },
     {
-        "duration": "18.0",
+        "duration": "20.0",
         "name": "rendering.mobile/no_op_touch_handler"
     },
     {
-        "duration": "18.0",
+        "duration": "19.0",
         "name": "rendering.mobile/nvidia_vertex_buffer_object"
     },
     {
@@ -2976,7 +2960,7 @@
         "name": "rendering.mobile/nytimes_mobile_2018"
     },
     {
-        "duration": "27.0",
+        "duration": "28.0",
         "name": "rendering.mobile/nytimes_scroll_2018"
     },
     {
@@ -2988,119 +2972,119 @@
         "name": "rendering.mobile/parallax_effect"
     },
     {
-        "duration": "18.0",
+        "duration": "19.0",
         "name": "rendering.mobile/particles"
     },
     {
-        "duration": "18.0",
+        "duration": "17.0",
         "name": "rendering.mobile/pbs_pathological_2018"
     },
     {
-        "duration": "14.0",
+        "duration": "15.0",
         "name": "rendering.mobile/physical_simulation"
     },
     {
-        "duration": "19.0",
+        "duration": "21.0",
         "name": "rendering.mobile/pinterest_2018"
     },
     {
-        "duration": "12.0",
+        "duration": "15.0",
         "name": "rendering.mobile/pinterest_mobile_2018"
     },
     {
-        "duration": "15.0",
+        "duration": "17.0",
         "name": "rendering.mobile/put_get_image_data"
     },
     {
-        "duration": "18.0",
+        "duration": "21.0",
         "name": "rendering.mobile/raf"
     },
     {
-        "duration": "18.0",
+        "duration": "21.0",
         "name": "rendering.mobile/raf_animation"
     },
     {
-        "duration": "19.0",
+        "duration": "21.0",
         "name": "rendering.mobile/raf_canvas"
     },
     {
-        "duration": "18.0",
+        "duration": "20.0",
         "name": "rendering.mobile/raf_touch_animation"
     },
     {
-        "duration": "23.0",
+        "duration": "21.0",
         "name": "rendering.mobile/recode_pathological_2018"
     },
     {
-        "duration": "21.0",
+        "duration": "23.0",
         "name": "rendering.mobile/reddit_mobile_2018"
     },
     {
-        "duration": "39.0",
+        "duration": "17.0",
         "name": "rendering.mobile/runway"
     },
     {
-        "duration": "19.0",
+        "duration": "18.0",
         "name": "rendering.mobile/san_angeles"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "rendering.mobile/second_batch_js_heavy"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "rendering.mobile/second_batch_js_light"
     },
     {
-        "duration": "12.0",
+        "duration": "16.0",
         "name": "rendering.mobile/second_batch_js_medium"
     },
     {
-        "duration": "21.0",
+        "duration": "23.0",
         "name": "rendering.mobile/sfgate_mobile_2018"
     },
     {
-        "duration": "24.0",
+        "duration": "25.0",
         "name": "rendering.mobile/silk_finance"
     },
     {
-        "duration": "18.0",
+        "duration": "20.0",
         "name": "rendering.mobile/simple_text_page"
     },
     {
-        "duration": "14.0",
+        "duration": "16.0",
         "name": "rendering.mobile/simple_touch_drag"
     },
     {
-        "duration": "19.0",
+        "duration": "20.0",
         "name": "rendering.mobile/slashdot_mobile_2018"
     },
     {
-        "duration": "15.0",
+        "duration": "18.0",
         "name": "rendering.mobile/slide_drawer"
     },
     {
-        "duration": "21.0",
+        "duration": "23.0",
         "name": "rendering.mobile/small_texture_uploads"
     },
     {
-        "duration": "22.0",
+        "duration": "17.0",
         "name": "rendering.mobile/smash_cat"
     },
     {
-        "duration": "21.0",
+        "duration": "17.0",
         "name": "rendering.mobile/spielzeugz"
     },
     {
-        "duration": "16.0",
+        "duration": "15.0",
         "name": "rendering.mobile/sticky_using_webkit"
     },
     {
-        "duration": "24.0",
+        "duration": "25.0",
         "name": "rendering.mobile/stress_hidey_bars"
     },
     {
-        "duration": "15.0",
+        "duration": "18.0",
         "name": "rendering.mobile/stroke_shapes"
     },
     {
@@ -3108,15 +3092,15 @@
         "name": "rendering.mobile/svg_icon_raster"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "rendering.mobile/swipe_action"
     },
     {
-        "duration": "16.0",
+        "duration": "18.0",
         "name": "rendering.mobile/swipe_to_dismiss"
     },
     {
-        "duration": "18.0",
+        "duration": "20.0",
         "name": "rendering.mobile/sync_scroll_offset"
     },
     {
@@ -3124,91 +3108,91 @@
         "name": "rendering.mobile/techcrunch_2018"
     },
     {
-        "duration": "22.0",
+        "duration": "23.0",
         "name": "rendering.mobile/techcrunch_mobile_2018"
     },
     {
-        "duration": "18.0",
+        "duration": "20.0",
         "name": "rendering.mobile/text_05000_pixels_per_second"
     },
     {
-        "duration": "18.0",
+        "duration": "21.0",
         "name": "rendering.mobile/text_10000_pixels_per_second"
     },
     {
-        "duration": "19.0",
+        "duration": "22.0",
         "name": "rendering.mobile/text_20000_pixels_per_second"
     },
     {
-        "duration": "17.0",
+        "duration": "19.0",
         "name": "rendering.mobile/text_40000_pixels_per_second"
     },
     {
-        "duration": "15.0",
+        "duration": "19.0",
         "name": "rendering.mobile/text_60000_pixels_per_second"
     },
     {
-        "duration": "15.0",
+        "duration": "17.0",
         "name": "rendering.mobile/text_75000_pixels_per_second"
     },
     {
-        "duration": "14.0",
+        "duration": "18.0",
         "name": "rendering.mobile/text_90000_pixels_per_second"
     },
     {
-        "duration": "19.0",
+        "duration": "21.0",
         "name": "rendering.mobile/text_constant_full_page_raster_05000_pixels_per_second"
     },
     {
-        "duration": "18.0",
+        "duration": "20.0",
         "name": "rendering.mobile/text_constant_full_page_raster_10000_pixels_per_second"
     },
     {
-        "duration": "19.0",
+        "duration": "23.0",
         "name": "rendering.mobile/text_constant_full_page_raster_20000_pixels_per_second"
     },
     {
-        "duration": "18.0",
+        "duration": "21.0",
         "name": "rendering.mobile/text_constant_full_page_raster_40000_pixels_per_second"
     },
     {
-        "duration": "16.0",
+        "duration": "18.0",
         "name": "rendering.mobile/text_constant_full_page_raster_60000_pixels_per_second"
     },
     {
-        "duration": "14.0",
+        "duration": "16.0",
         "name": "rendering.mobile/text_constant_full_page_raster_75000_pixels_per_second"
     },
     {
-        "duration": "14.0",
+        "duration": "16.0",
         "name": "rendering.mobile/text_constant_full_page_raster_90000_pixels_per_second"
     },
     {
-        "duration": "16.0",
+        "duration": "20.0",
         "name": "rendering.mobile/text_hover_05000_pixels_per_second"
     },
     {
-        "duration": "16.0",
+        "duration": "19.0",
         "name": "rendering.mobile/text_hover_10000_pixels_per_second"
     },
     {
-        "duration": "16.0",
+        "duration": "19.0",
         "name": "rendering.mobile/text_hover_20000_pixels_per_second"
     },
     {
-        "duration": "15.0",
+        "duration": "18.0",
         "name": "rendering.mobile/text_hover_40000_pixels_per_second"
     },
     {
-        "duration": "14.0",
+        "duration": "17.0",
         "name": "rendering.mobile/text_hover_60000_pixels_per_second"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "rendering.mobile/text_hover_75000_pixels_per_second"
     },
     {
-        "duration": "12.0",
+        "duration": "17.0",
         "name": "rendering.mobile/text_hover_90000_pixels_per_second"
     },
     {
@@ -3220,23 +3204,23 @@
         "name": "rendering.mobile/theverge_mobile_2018"
     },
     {
-        "duration": "20.0",
+        "duration": "23.0",
         "name": "rendering.mobile/toggle_drawer"
     },
     {
-        "duration": "18.0",
+        "duration": "20.0",
         "name": "rendering.mobile/touch_handler_scrolling"
     },
     {
-        "duration": "21.0",
+        "duration": "23.0",
         "name": "rendering.mobile/transform_transitions"
     },
     {
-        "duration": "21.0",
+        "duration": "23.0",
         "name": "rendering.mobile/transform_transitions_js_block"
     },
     {
-        "duration": "17.0",
+        "duration": "19.0",
         "name": "rendering.mobile/twitch_2018"
     },
     {
@@ -3244,83 +3228,91 @@
         "name": "rendering.mobile/twitch_mobile_pinch_2018"
     },
     {
-        "duration": "21.0",
+        "duration": "22.0",
         "name": "rendering.mobile/twitter_2018"
     },
     {
-        "duration": "14.0",
+        "duration": "15.0",
         "name": "rendering.mobile/twitter_mobile_2018"
     },
     {
-        "duration": "18.0",
+        "duration": "22.0",
         "name": "rendering.mobile/update_history_state"
     },
     {
-        "duration": "15.0",
+        "duration": "16.0",
         "name": "rendering.mobile/usatoday_mobile_2018"
     },
     {
-        "duration": "17.0",
+        "duration": "18.0",
         "name": "rendering.mobile/vertical_expansion"
     },
     {
-        "duration": "21.0",
+        "duration": "25.0",
         "name": "rendering.mobile/web_animation_value_type_color"
     },
     {
-        "duration": "22.0",
+        "duration": "24.0",
         "name": "rendering.mobile/web_animation_value_type_length_3d"
     },
     {
-        "duration": "23.0",
+        "duration": "25.0",
         "name": "rendering.mobile/web_animation_value_type_length_complex"
     },
     {
-        "duration": "22.0",
+        "duration": "24.0",
         "name": "rendering.mobile/web_animation_value_type_length_simple"
     },
     {
-        "duration": "22.0",
+        "duration": "26.0",
         "name": "rendering.mobile/web_animation_value_type_path"
     },
     {
-        "duration": "20.0",
+        "duration": "24.0",
         "name": "rendering.mobile/web_animation_value_type_shadow"
     },
     {
-        "duration": "22.0",
+        "duration": "25.0",
         "name": "rendering.mobile/web_animation_value_type_transform_complex"
     },
     {
-        "duration": "22.0",
+        "duration": "24.0",
         "name": "rendering.mobile/web_animation_value_type_transform_simple"
     },
     {
-        "duration": "24.0",
+        "duration": "30.0",
         "name": "rendering.mobile/web_animations_many_keyframes"
     },
     {
-        "duration": "21.0",
+        "duration": "25.0",
         "name": "rendering.mobile/web_animations_set_current_time"
     },
     {
-        "duration": "26.0",
+        "duration": "25.0",
         "name": "rendering.mobile/web_animations_simultaneous"
     },
     {
-        "duration": "34.0",
+        "duration": "25.0",
         "name": "rendering.mobile/web_animations_staggered_chaining"
     },
     {
-        "duration": "20.0",
+        "duration": "24.0",
         "name": "rendering.mobile/web_animations_staggered_infinite_iterations"
     },
     {
-        "duration": "22.0",
+        "duration": "25.0",
         "name": "rendering.mobile/web_animations_staggered_triggering_page"
     },
     {
-        "duration": "21.0",
+        "duration": "19.0",
+        "name": "rendering.mobile/webp_decoding_rgb_and_gpu_rasterization"
+    },
+    {
+        "duration": "17.0",
+        "name": "rendering.mobile/webp_decoding_yuv_and_gpu_rasterization"
+    },
+    {
+        "duration": "22.0",
         "name": "rendering.mobile/wikipedia_2018"
     },
     {
@@ -3328,11 +3320,11 @@
         "name": "rendering.mobile/wikipedia_delayed_scroll_start_2018"
     },
     {
-        "duration": "20.0",
+        "duration": "21.0",
         "name": "rendering.mobile/wikipedia_mobile_2018"
     },
     {
-        "duration": "21.0",
+        "duration": "22.0",
         "name": "rendering.mobile/wordpress_2018"
     },
     {
@@ -3344,15 +3336,15 @@
         "name": "rendering.mobile/worldjournal_mobile_2018"
     },
     {
-        "duration": "25.0",
+        "duration": "22.0",
         "name": "rendering.mobile/wow_wiki_pathological_2018"
     },
     {
-        "duration": "36.0",
+        "duration": "35.0",
         "name": "rendering.mobile/wowwiki_mobile_2018"
     },
     {
-        "duration": "24.0",
+        "duration": "23.0",
         "name": "rendering.mobile/wsj_mobile_2018"
     },
     {
@@ -3360,11 +3352,11 @@
         "name": "rendering.mobile/yahoo_answers_2018"
     },
     {
-        "duration": "16.0",
+        "duration": "18.0",
         "name": "rendering.mobile/yahoo_news_2018"
     },
     {
-        "duration": "20.0",
+        "duration": "21.0",
         "name": "rendering.mobile/yahoo_news_mobile_2018"
     },
     {
@@ -3376,167 +3368,63 @@
         "name": "rendering.mobile/yahoo_sports_pathological_2018"
     },
     {
-        "duration": "15.0",
+        "duration": "16.0",
         "name": "rendering.mobile/youtube_2018"
     },
     {
-        "duration": "14.0",
+        "duration": "15.0",
         "name": "rendering.mobile/youtube_mobile_2018"
     },
     {
-        "duration": "37.0",
-        "name": "rendering.mobile/yuv_decoding"
-    },
-    {
-        "duration": "73.0",
-        "name": "rendering.mobile/yuv_decoding_gpu_rasterization_and_decoding"
-    },
-    {
-        "duration": "20.0",
+        "duration": "21.0",
         "name": "rendering.mobile/zdnet_pathological_2018"
     },
     {
-        "duration": "17.0",
+        "duration": "16.0",
         "name": "rendering.mobile/zoom_in_animation"
     },
     {
-        "duration": "21.0",
-        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/amazon_pinch_2018"
-    },
-    {
-        "duration": "17.0",
-        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/blogspot_pinch_2018"
-    },
-    {
-        "duration": "20.0",
-        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/booking_pinch_2018"
-    },
-    {
-        "duration": "21.0",
-        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/espn_pinch_2018"
-    },
-    {
-        "duration": "21.0",
-        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/facebook_pinch_2018"
-    },
-    {
-        "duration": "36.0",
-        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/gmail_pinch_2018"
-    },
-    {
-        "duration": "18.0",
-        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/google_calendar_pinch_2018"
-    },
-    {
-        "duration": "18.0",
-        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/google_image_pinch_2018"
-    },
-    {
-        "duration": "19.0",
-        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/twitter_pinch_2018"
-    },
-    {
-        "duration": "31.0",
-        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/yahoo_news_pinch_2018"
-    },
-    {
-        "duration": "29.0",
-        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/yahoo_sports_pinch_2018"
-    },
-    {
-        "duration": "20.0",
-        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/youtube_pinch_2018"
-    },
-    {
-        "duration": "20.0",
-        "name": "smoothness.tough_pinch_zoom_cases/amazon_pinch_2018"
-    },
-    {
-        "duration": "16.0",
-        "name": "smoothness.tough_pinch_zoom_cases/blogspot_pinch_2018"
-    },
-    {
-        "duration": "20.0",
-        "name": "smoothness.tough_pinch_zoom_cases/booking_pinch_2018"
-    },
-    {
-        "duration": "20.0",
-        "name": "smoothness.tough_pinch_zoom_cases/espn_pinch_2018"
-    },
-    {
-        "duration": "19.0",
-        "name": "smoothness.tough_pinch_zoom_cases/facebook_pinch_2018"
-    },
-    {
-        "duration": "33.0",
-        "name": "smoothness.tough_pinch_zoom_cases/gmail_pinch_2018"
-    },
-    {
-        "duration": "17.0",
-        "name": "smoothness.tough_pinch_zoom_cases/google_calendar_pinch_2018"
-    },
-    {
-        "duration": "16.0",
-        "name": "smoothness.tough_pinch_zoom_cases/google_image_pinch_2018"
-    },
-    {
-        "duration": "19.0",
-        "name": "smoothness.tough_pinch_zoom_cases/twitter_pinch_2018"
-    },
-    {
-        "duration": "29.0",
-        "name": "smoothness.tough_pinch_zoom_cases/yahoo_news_pinch_2018"
-    },
-    {
-        "duration": "30.0",
-        "name": "smoothness.tough_pinch_zoom_cases/yahoo_sports_pinch_2018"
-    },
-    {
-        "duration": "19.0",
-        "name": "smoothness.tough_pinch_zoom_cases/youtube_pinch_2018"
-    },
-    {
-        "duration": "34.0",
+        "duration": "39.0",
         "name": "speedometer-future/http://browserbench.org/Speedometer/"
     },
     {
-        "duration": "33.0",
+        "duration": "44.0",
         "name": "speedometer/http://browserbench.org/Speedometer/"
     },
     {
-        "duration": "56.0",
+        "duration": "61.0",
         "name": "speedometer2-future/Speedometer2"
     },
     {
-        "duration": "54.0",
+        "duration": "60.0",
         "name": "speedometer2/Speedometer2"
     },
     {
-        "duration": "136.0",
+        "duration": "157.0",
         "name": "startup.mobile/cct:coldish:bbc"
     },
     {
-        "duration": "144.0",
+        "duration": "152.0",
         "name": "startup.mobile/intent:coldish:bbc"
     },
     {
-        "duration": "117.0",
+        "duration": "136.0",
         "name": "startup.mobile/intent:warm:bbc"
     },
     {
-        "duration": "91.0",
+        "duration": "105.0",
         "name": "startup.mobile/maps_pwa:with_http_cache"
     },
     {
-        "duration": "20.0",
+        "duration": "21.0",
         "name": "system_health.common_mobile/background:media:imgur"
     },
     {
-        "duration": "21.0",
+        "duration": "22.0",
         "name": "system_health.common_mobile/background:search:google"
     },
     {
-        "duration": "20.0",
+        "duration": "22.0",
         "name": "system_health.common_mobile/background:social:facebook"
     },
     {
@@ -3544,7 +3432,7 @@
         "name": "system_health.common_mobile/browse:chrome:newtab"
     },
     {
-        "duration": "26.0",
+        "duration": "29.0",
         "name": "system_health.common_mobile/browse:chrome:omnibox"
     },
     {
@@ -3552,7 +3440,7 @@
         "name": "system_health.common_mobile/browse:media:facebook_photos"
     },
     {
-        "duration": "45.0",
+        "duration": "46.0",
         "name": "system_health.common_mobile/browse:media:flickr_infinite_scroll"
     },
     {
@@ -3564,119 +3452,111 @@
         "name": "system_health.common_mobile/browse:media:imgur"
     },
     {
-        "duration": "91.0",
+        "duration": "88.0",
         "name": "system_health.common_mobile/browse:media:youtube"
     },
     {
-        "duration": "65.0",
-        "name": "system_health.common_mobile/browse:news:cnn"
-    },
-    {
-        "duration": "64.0",
+        "duration": "56.0",
         "name": "system_health.common_mobile/browse:news:cnn:2018"
     },
     {
-        "duration": "61.0",
+        "duration": "65.0",
         "name": "system_health.common_mobile/browse:news:cricbuzz"
     },
     {
-        "duration": "55.0",
+        "duration": "51.0",
         "name": "system_health.common_mobile/browse:news:qq"
     },
     {
-        "duration": "49.0",
+        "duration": "50.0",
         "name": "system_health.common_mobile/browse:news:reddit"
     },
     {
-        "duration": "100.0",
+        "duration": "94.0",
         "name": "system_health.common_mobile/browse:news:toi"
     },
     {
-        "duration": "49.0",
+        "duration": "52.0",
         "name": "system_health.common_mobile/browse:news:washingtonpost"
     },
     {
-        "duration": "25.0",
+        "duration": "28.0",
         "name": "system_health.common_mobile/browse:search:amp:2018"
     },
     {
-        "duration": "57.0",
+        "duration": "27.0",
+        "name": "system_health.common_mobile/browse:search:amp:sxg:2019"
+    },
+    {
+        "duration": "58.0",
         "name": "system_health.common_mobile/browse:shopping:amazon"
     },
     {
-        "duration": "29.0",
+        "duration": "30.0",
         "name": "system_health.common_mobile/browse:shopping:lazada"
     },
     {
-        "duration": "64.0",
+        "duration": "67.0",
         "name": "system_health.common_mobile/browse:social:facebook"
     },
     {
-        "duration": "95.0",
+        "duration": "92.0",
         "name": "system_health.common_mobile/browse:social:facebook_infinite_scroll"
     },
     {
-        "duration": "81.0",
+        "duration": "77.0",
         "name": "system_health.common_mobile/browse:social:facebook_infinite_scroll:2018"
     },
     {
-        "duration": "77.0",
+        "duration": "78.0",
         "name": "system_health.common_mobile/browse:social:instagram"
     },
     {
-        "duration": "78.0",
+        "duration": "75.0",
         "name": "system_health.common_mobile/browse:social:pinterest_infinite_scroll"
     },
     {
-        "duration": "82.0",
-        "name": "system_health.common_mobile/browse:social:tumblr_infinite_scroll"
-    },
-    {
         "duration": "76.0",
         "name": "system_health.common_mobile/browse:social:tumblr_infinite_scroll:2018"
     },
     {
-        "duration": "49.0",
+        "duration": "51.0",
         "name": "system_health.common_mobile/browse:social:twitter"
     },
     {
-        "duration": "59.0",
+        "duration": "57.0",
         "name": "system_health.common_mobile/browse:tech:discourse_infinite_scroll"
     },
     {
-        "duration": "79.0",
+        "duration": "75.0",
         "name": "system_health.common_mobile/browse:tech:discourse_infinite_scroll:2018"
     },
     {
-        "duration": "42.0",
+        "duration": "44.0",
         "name": "system_health.common_mobile/browse:tools:maps"
     },
     {
-        "duration": "23.0",
+        "duration": "28.0",
         "name": "system_health.common_mobile/load:chrome:blank"
     },
     {
-        "duration": "19.0",
+        "duration": "22.0",
         "name": "system_health.common_mobile/load:games:bubbles"
     },
     {
-        "duration": "17.0",
+        "duration": "19.0",
         "name": "system_health.common_mobile/load:games:lazors"
     },
     {
-        "duration": "24.0",
-        "name": "system_health.common_mobile/load:games:spychase"
-    },
-    {
         "duration": "26.0",
         "name": "system_health.common_mobile/load:games:spychase:2018"
     },
     {
-        "duration": "21.0",
+        "duration": "24.0",
         "name": "system_health.common_mobile/load:media:dailymotion"
     },
     {
-        "duration": "18.0",
+        "duration": "21.0",
         "name": "system_health.common_mobile/load:media:facebook_photos"
     },
     {
@@ -3684,347 +3564,271 @@
         "name": "system_health.common_mobile/load:media:flickr:2018"
     },
     {
-        "duration": "18.0",
-        "name": "system_health.common_mobile/load:media:google_images"
-    },
-    {
-        "duration": "19.0",
+        "duration": "21.0",
         "name": "system_health.common_mobile/load:media:google_images:2018"
     },
     {
-        "duration": "18.0",
-        "name": "system_health.common_mobile/load:media:imgur"
-    },
-    {
-        "duration": "23.0",
+        "duration": "26.0",
         "name": "system_health.common_mobile/load:media:imgur:2018"
     },
     {
-        "duration": "18.0",
-        "name": "system_health.common_mobile/load:media:soundcloud"
-    },
-    {
-        "duration": "19.0",
+        "duration": "20.0",
         "name": "system_health.common_mobile/load:media:soundcloud:2018"
     },
     {
-        "duration": "18.0",
-        "name": "system_health.common_mobile/load:media:youtube"
-    },
-    {
-        "duration": "21.0",
+        "duration": "22.0",
         "name": "system_health.common_mobile/load:media:youtube:2018"
     },
     {
-        "duration": "24.0",
-        "name": "system_health.common_mobile/load:news:cnn"
-    },
-    {
-        "duration": "24.0",
+        "duration": "25.0",
         "name": "system_health.common_mobile/load:news:cnn:2018"
     },
     {
-        "duration": "21.0",
+        "duration": "23.0",
         "name": "system_health.common_mobile/load:news:irctc"
     },
     {
-        "duration": "21.0",
+        "duration": "23.0",
         "name": "system_health.common_mobile/load:news:nytimes"
     },
     {
-        "duration": "21.0",
+        "duration": "23.0",
         "name": "system_health.common_mobile/load:news:qq"
     },
     {
-        "duration": "19.0",
+        "duration": "22.0",
         "name": "system_health.common_mobile/load:news:reddit"
     },
     {
-        "duration": "20.0",
+        "duration": "24.0",
         "name": "system_health.common_mobile/load:news:washingtonpost"
     },
     {
         "duration": "19.0",
-        "name": "system_health.common_mobile/load:news:wikipedia"
-    },
-    {
-        "duration": "19.0",
         "name": "system_health.common_mobile/load:news:wikipedia:2018"
     },
     {
         "duration": "22.0",
-        "name": "system_health.common_mobile/load:search:baidu"
-    },
-    {
-        "duration": "22.0",
         "name": "system_health.common_mobile/load:search:baidu:2018"
     },
     {
-        "duration": "18.0",
-        "name": "system_health.common_mobile/load:search:ebay"
-    },
-    {
-        "duration": "20.0",
+        "duration": "22.0",
         "name": "system_health.common_mobile/load:search:ebay:2018"
     },
     {
-        "duration": "18.0",
-        "name": "system_health.common_mobile/load:search:google"
-    },
-    {
         "duration": "20.0",
         "name": "system_health.common_mobile/load:search:google:2018"
     },
     {
-        "duration": "19.0",
+        "duration": "23.0",
         "name": "system_health.common_mobile/load:search:taobao"
     },
     {
-        "duration": "17.0",
-        "name": "system_health.common_mobile/load:search:yahoo"
-    },
-    {
-        "duration": "18.0",
+        "duration": "22.0",
         "name": "system_health.common_mobile/load:search:yahoo:2018"
     },
     {
-        "duration": "18.0",
-        "name": "system_health.common_mobile/load:search:yandex"
-    },
-    {
-        "duration": "19.0",
+        "duration": "22.0",
         "name": "system_health.common_mobile/load:search:yandex:2018"
     },
     {
-        "duration": "19.0",
+        "duration": "21.0",
         "name": "system_health.common_mobile/load:social:twitter"
     },
     {
-        "duration": "18.0",
+        "duration": "22.0",
         "name": "system_health.common_mobile/load:tools:docs"
     },
     {
-        "duration": "19.0",
+        "duration": "23.0",
         "name": "system_health.common_mobile/load:tools:drive"
     },
     {
-        "duration": "19.0",
+        "duration": "21.0",
         "name": "system_health.common_mobile/load:tools:dropbox"
     },
     {
-        "duration": "19.0",
-        "name": "system_health.common_mobile/load:tools:stackoverflow"
-    },
-    {
-        "duration": "19.0",
+        "duration": "22.0",
         "name": "system_health.common_mobile/load:tools:stackoverflow:2018"
     },
     {
-        "duration": "21.0",
+        "duration": "25.0",
         "name": "system_health.common_mobile/load:tools:weather"
     },
     {
-        "duration": "24.0",
+        "duration": "26.0",
         "name": "system_health.memory_mobile/background:media:imgur"
     },
     {
-        "duration": "24.0",
+        "duration": "27.0",
         "name": "system_health.memory_mobile/background:search:google"
     },
     {
-        "duration": "23.0",
+        "duration": "27.0",
         "name": "system_health.memory_mobile/background:social:facebook"
     },
     {
-        "duration": "76.0",
+        "duration": "78.0",
         "name": "system_health.memory_mobile/browse:chrome:newtab"
     },
     {
-        "duration": "30.0",
+        "duration": "32.0",
         "name": "system_health.memory_mobile/browse:chrome:omnibox"
     },
     {
-        "duration": "74.0",
+        "duration": "77.0",
         "name": "system_health.memory_mobile/browse:media:facebook_photos"
     },
     {
-        "duration": "45.0",
+        "duration": "48.0",
         "name": "system_health.memory_mobile/browse:media:flickr_infinite_scroll"
     },
     {
-        "duration": "43.0",
+        "duration": "44.0",
         "name": "system_health.memory_mobile/browse:media:googleplaystore:2019"
     },
     {
-        "duration": "69.0",
+        "duration": "71.0",
         "name": "system_health.memory_mobile/browse:media:imgur"
     },
     {
-        "duration": "81.0",
+        "duration": "83.0",
         "name": "system_health.memory_mobile/browse:media:youtube"
     },
     {
-        "duration": "59.0",
-        "name": "system_health.memory_mobile/browse:news:cnn"
-    },
-    {
-        "duration": "51.0",
+        "duration": "54.0",
         "name": "system_health.memory_mobile/browse:news:cnn:2018"
     },
     {
-        "duration": "60.0",
+        "duration": "63.0",
         "name": "system_health.memory_mobile/browse:news:cricbuzz"
     },
     {
-        "duration": "55.0",
+        "duration": "50.0",
         "name": "system_health.memory_mobile/browse:news:qq"
     },
     {
-        "duration": "49.0",
+        "duration": "51.0",
         "name": "system_health.memory_mobile/browse:news:reddit"
     },
     {
-        "duration": "74.0",
+        "duration": "77.0",
         "name": "system_health.memory_mobile/browse:news:toi"
     },
     {
-        "duration": "48.0",
+        "duration": "49.0",
         "name": "system_health.memory_mobile/browse:news:washingtonpost"
     },
     {
-        "duration": "25.0",
+        "duration": "27.0",
         "name": "system_health.memory_mobile/browse:search:amp:2018"
     },
     {
-        "duration": "52.0",
+        "duration": "29.0",
+        "name": "system_health.memory_mobile/browse:search:amp:sxg:2019"
+    },
+    {
+        "duration": "55.0",
         "name": "system_health.memory_mobile/browse:shopping:amazon"
     },
     {
-        "duration": "31.0",
+        "duration": "33.0",
         "name": "system_health.memory_mobile/browse:shopping:lazada"
     },
     {
-        "duration": "62.0",
+        "duration": "64.0",
         "name": "system_health.memory_mobile/browse:social:facebook"
     },
     {
-        "duration": "70.0",
+        "duration": "72.0",
         "name": "system_health.memory_mobile/browse:social:facebook_infinite_scroll"
     },
     {
-        "duration": "70.0",
+        "duration": "71.0",
         "name": "system_health.memory_mobile/browse:social:facebook_infinite_scroll:2018"
     },
     {
-        "duration": "72.0",
+        "duration": "75.0",
         "name": "system_health.memory_mobile/browse:social:instagram"
     },
     {
-        "duration": "70.0",
+        "duration": "71.0",
         "name": "system_health.memory_mobile/browse:social:pinterest_infinite_scroll"
     },
     {
-        "duration": "69.0",
-        "name": "system_health.memory_mobile/browse:social:tumblr_infinite_scroll"
-    },
-    {
-        "duration": "67.0",
+        "duration": "68.0",
         "name": "system_health.memory_mobile/browse:social:tumblr_infinite_scroll:2018"
     },
     {
-        "duration": "49.0",
+        "duration": "51.0",
         "name": "system_health.memory_mobile/browse:social:twitter"
     },
     {
-        "duration": "54.0",
+        "duration": "56.0",
         "name": "system_health.memory_mobile/browse:tech:discourse_infinite_scroll"
     },
     {
-        "duration": "67.0",
+        "duration": "70.0",
         "name": "system_health.memory_mobile/browse:tech:discourse_infinite_scroll:2018"
     },
     {
-        "duration": "44.0",
+        "duration": "46.0",
         "name": "system_health.memory_mobile/browse:tools:maps"
     },
     {
-        "duration": "24.0",
+        "duration": "27.0",
         "name": "system_health.memory_mobile/load:chrome:blank"
     },
     {
-        "duration": "22.0",
+        "duration": "25.0",
         "name": "system_health.memory_mobile/load:games:bubbles"
     },
     {
-        "duration": "22.0",
+        "duration": "24.0",
         "name": "system_health.memory_mobile/load:games:lazors"
     },
     {
-        "duration": "27.0",
-        "name": "system_health.memory_mobile/load:games:spychase"
-    },
-    {
-        "duration": "27.0",
+        "duration": "29.0",
         "name": "system_health.memory_mobile/load:games:spychase:2018"
     },
     {
-        "duration": "24.0",
+        "duration": "26.0",
         "name": "system_health.memory_mobile/load:media:dailymotion"
     },
     {
-        "duration": "22.0",
+        "duration": "26.0",
         "name": "system_health.memory_mobile/load:media:facebook_photos"
     },
     {
-        "duration": "25.0",
+        "duration": "26.0",
         "name": "system_health.memory_mobile/load:media:flickr:2018"
     },
     {
-        "duration": "22.0",
-        "name": "system_health.memory_mobile/load:media:google_images"
-    },
-    {
-        "duration": "23.0",
+        "duration": "25.0",
         "name": "system_health.memory_mobile/load:media:google_images:2018"
     },
     {
-        "duration": "22.0",
-        "name": "system_health.memory_mobile/load:media:imgur"
-    },
-    {
-        "duration": "25.0",
+        "duration": "26.0",
         "name": "system_health.memory_mobile/load:media:imgur:2018"
     },
     {
-        "duration": "22.0",
-        "name": "system_health.memory_mobile/load:media:soundcloud"
-    },
-    {
-        "duration": "23.0",
+        "duration": "25.0",
         "name": "system_health.memory_mobile/load:media:soundcloud:2018"
     },
     {
-        "duration": "22.0",
-        "name": "system_health.memory_mobile/load:media:youtube"
-    },
-    {
-        "duration": "23.0",
+        "duration": "25.0",
         "name": "system_health.memory_mobile/load:media:youtube:2018"
     },
     {
-        "duration": "30.0",
-        "name": "system_health.memory_mobile/load:news:cnn"
-    },
-    {
-        "duration": "28.0",
+        "duration": "29.0",
         "name": "system_health.memory_mobile/load:news:cnn:2018"
     },
     {
-        "duration": "23.0",
+        "duration": "26.0",
         "name": "system_health.memory_mobile/load:news:irctc"
     },
     {
-        "duration": "25.0",
+        "duration": "26.0",
         "name": "system_health.memory_mobile/load:news:nytimes"
     },
     {
@@ -4032,195 +3836,163 @@
         "name": "system_health.memory_mobile/load:news:qq"
     },
     {
-        "duration": "23.0",
+        "duration": "25.0",
         "name": "system_health.memory_mobile/load:news:reddit"
     },
     {
-        "duration": "25.0",
+        "duration": "26.0",
         "name": "system_health.memory_mobile/load:news:washingtonpost"
     },
     {
-        "duration": "23.0",
-        "name": "system_health.memory_mobile/load:news:wikipedia"
-    },
-    {
-        "duration": "23.0",
+        "duration": "24.0",
         "name": "system_health.memory_mobile/load:news:wikipedia:2018"
     },
     {
-        "duration": "29.0",
-        "name": "system_health.memory_mobile/load:search:baidu"
-    },
-    {
-        "duration": "26.0",
+        "duration": "27.0",
         "name": "system_health.memory_mobile/load:search:baidu:2018"
     },
     {
-        "duration": "22.0",
-        "name": "system_health.memory_mobile/load:search:ebay"
-    },
-    {
-        "duration": "23.0",
+        "duration": "25.0",
         "name": "system_health.memory_mobile/load:search:ebay:2018"
     },
     {
-        "duration": "23.0",
-        "name": "system_health.memory_mobile/load:search:google"
-    },
-    {
-        "duration": "23.0",
+        "duration": "25.0",
         "name": "system_health.memory_mobile/load:search:google:2018"
     },
     {
-        "duration": "22.0",
+        "duration": "29.0",
         "name": "system_health.memory_mobile/load:search:taobao"
     },
     {
-        "duration": "22.0",
-        "name": "system_health.memory_mobile/load:search:yahoo"
-    },
-    {
-        "duration": "22.0",
+        "duration": "24.0",
         "name": "system_health.memory_mobile/load:search:yahoo:2018"
     },
     {
-        "duration": "22.0",
-        "name": "system_health.memory_mobile/load:search:yandex"
-    },
-    {
-        "duration": "23.0",
+        "duration": "25.0",
         "name": "system_health.memory_mobile/load:search:yandex:2018"
     },
     {
-        "duration": "23.0",
+        "duration": "24.0",
         "name": "system_health.memory_mobile/load:social:twitter"
     },
     {
-        "duration": "22.0",
+        "duration": "25.0",
         "name": "system_health.memory_mobile/load:tools:docs"
     },
     {
-        "duration": "23.0",
+        "duration": "25.0",
         "name": "system_health.memory_mobile/load:tools:drive"
     },
     {
-        "duration": "22.0",
+        "duration": "24.0",
         "name": "system_health.memory_mobile/load:tools:dropbox"
     },
     {
-        "duration": "23.0",
-        "name": "system_health.memory_mobile/load:tools:stackoverflow"
-    },
-    {
-        "duration": "23.0",
+        "duration": "25.0",
         "name": "system_health.memory_mobile/load:tools:stackoverflow:2018"
     },
     {
-        "duration": "24.0",
+        "duration": "26.0",
         "name": "system_health.memory_mobile/load:tools:weather"
     },
     {
-        "duration": "10.0",
+        "duration": "12.0",
         "name": "tracing.tracing_with_background_memory_infra/Facebook"
     },
     {
-        "duration": "11.0",
+        "duration": "14.0",
         "name": "tracing.tracing_with_background_memory_infra/Wikipedia"
     },
     {
-        "duration": "10.0",
+        "duration": "15.0",
         "name": "tracing.tracing_with_background_memory_infra/http://www.amazon.com"
     },
     {
-        "duration": "10.0",
+        "duration": "12.0",
         "name": "tracing.tracing_with_background_memory_infra/http://www.ask.com/"
     },
     {
-        "duration": "9.0",
+        "duration": "13.0",
         "name": "tracing.tracing_with_background_memory_infra/http://www.bing.com/"
     },
     {
-        "duration": "11.0",
+        "duration": "15.0",
         "name": "tracing.tracing_with_background_memory_infra/http://www.yahoo.com/"
     },
     {
-        "duration": "11.0",
+        "duration": "13.0",
         "name": "tracing.tracing_with_background_memory_infra/http://www.youtube.com"
     },
     {
-        "duration": "14.0",
+        "duration": "16.0",
         "name": "tracing.tracing_with_background_memory_infra/https://www.google.com/#hl=en&q=barack+obama"
     },
     {
-        "duration": "11.0",
+        "duration": "14.0",
         "name": "tracing.tracing_with_background_memory_infra/https://www.google.com/calendar/"
     },
     {
-        "duration": "88.0",
+        "duration": "87.0",
         "name": "v8.browsing_mobile-future/browse:chrome:newtab"
     },
     {
-        "duration": "28.0",
+        "duration": "32.0",
         "name": "v8.browsing_mobile-future/browse:chrome:omnibox"
     },
     {
-        "duration": "82.0",
+        "duration": "84.0",
         "name": "v8.browsing_mobile-future/browse:media:facebook_photos"
     },
     {
-        "duration": "54.0",
+        "duration": "52.0",
         "name": "v8.browsing_mobile-future/browse:media:flickr_infinite_scroll"
     },
     {
-        "duration": "47.0",
+        "duration": "48.0",
         "name": "v8.browsing_mobile-future/browse:media:googleplaystore:2019"
     },
     {
-        "duration": "76.0",
+        "duration": "77.0",
         "name": "v8.browsing_mobile-future/browse:media:imgur"
     },
     {
-        "duration": "101.0",
+        "duration": "99.0",
         "name": "v8.browsing_mobile-future/browse:media:youtube"
     },
     {
-        "duration": "115.0",
-        "name": "v8.browsing_mobile-future/browse:news:cnn"
-    },
-    {
-        "duration": "73.0",
+        "duration": "69.0",
         "name": "v8.browsing_mobile-future/browse:news:cnn:2018"
     },
     {
-        "duration": "61.0",
+        "duration": "67.0",
         "name": "v8.browsing_mobile-future/browse:news:cricbuzz"
     },
     {
-        "duration": "60.0",
+        "duration": "65.0",
         "name": "v8.browsing_mobile-future/browse:news:qq"
     },
     {
-        "duration": "53.0",
+        "duration": "54.0",
         "name": "v8.browsing_mobile-future/browse:news:reddit"
     },
     {
-        "duration": "105.0",
-        "name": "v8.browsing_mobile-future/browse:news:toi"
-    },
-    {
         "duration": "54.0",
         "name": "v8.browsing_mobile-future/browse:news:washingtonpost"
     },
     {
-        "duration": "27.0",
+        "duration": "29.0",
         "name": "v8.browsing_mobile-future/browse:search:amp:2018"
     },
     {
-        "duration": "65.0",
+        "duration": "27.0",
+        "name": "v8.browsing_mobile-future/browse:search:amp:sxg:2019"
+    },
+    {
+        "duration": "63.0",
         "name": "v8.browsing_mobile-future/browse:shopping:amazon"
     },
     {
-        "duration": "32.0",
+        "duration": "35.0",
         "name": "v8.browsing_mobile-future/browse:shopping:lazada"
     },
     {
@@ -4228,111 +4000,111 @@
         "name": "v8.browsing_mobile-future/browse:social:facebook"
     },
     {
-        "duration": "93.0",
+        "duration": "110.0",
+        "name": "v8.browsing_mobile-future/browse:social:facebook_infinite_scroll"
+    },
+    {
+        "duration": "91.0",
         "name": "v8.browsing_mobile-future/browse:social:facebook_infinite_scroll:2018"
     },
     {
-        "duration": "89.0",
+        "duration": "86.0",
         "name": "v8.browsing_mobile-future/browse:social:instagram"
     },
     {
-        "duration": "90.0",
+        "duration": "86.0",
         "name": "v8.browsing_mobile-future/browse:social:pinterest_infinite_scroll"
     },
     {
-        "duration": "94.0",
-        "name": "v8.browsing_mobile-future/browse:social:tumblr_infinite_scroll"
-    },
-    {
-        "duration": "88.0",
+        "duration": "87.0",
         "name": "v8.browsing_mobile-future/browse:social:tumblr_infinite_scroll:2018"
     },
     {
-        "duration": "53.0",
+        "duration": "54.0",
         "name": "v8.browsing_mobile-future/browse:social:twitter"
     },
     {
+        "duration": "68.0",
+        "name": "v8.browsing_mobile-future/browse:tech:discourse_infinite_scroll"
+    },
+    {
         "duration": "91.0",
         "name": "v8.browsing_mobile-future/browse:tech:discourse_infinite_scroll:2018"
     },
     {
-        "duration": "46.0",
+        "duration": "48.0",
         "name": "v8.browsing_mobile-future/browse:tools:maps"
     },
     {
-        "duration": "87.0",
+        "duration": "85.0",
         "name": "v8.browsing_mobile/browse:chrome:newtab"
     },
     {
-        "duration": "27.0",
+        "duration": "30.0",
         "name": "v8.browsing_mobile/browse:chrome:omnibox"
     },
     {
-        "duration": "86.0",
+        "duration": "82.0",
         "name": "v8.browsing_mobile/browse:media:facebook_photos"
     },
     {
-        "duration": "52.0",
+        "duration": "51.0",
         "name": "v8.browsing_mobile/browse:media:flickr_infinite_scroll"
     },
     {
-        "duration": "49.0",
+        "duration": "48.0",
         "name": "v8.browsing_mobile/browse:media:googleplaystore:2019"
     },
     {
-        "duration": "77.0",
+        "duration": "78.0",
         "name": "v8.browsing_mobile/browse:media:imgur"
     },
     {
-        "duration": "101.0",
+        "duration": "98.0",
         "name": "v8.browsing_mobile/browse:media:youtube"
     },
     {
-        "duration": "112.0",
-        "name": "v8.browsing_mobile/browse:news:cnn"
-    },
-    {
-        "duration": "74.0",
+        "duration": "68.0",
         "name": "v8.browsing_mobile/browse:news:cnn:2018"
     },
     {
-        "duration": "63.0",
+        "duration": "68.0",
         "name": "v8.browsing_mobile/browse:news:cricbuzz"
     },
     {
-        "duration": "60.0",
+        "duration": "61.0",
         "name": "v8.browsing_mobile/browse:news:qq"
     },
     {
-        "duration": "52.0",
+        "duration": "53.0",
         "name": "v8.browsing_mobile/browse:news:reddit"
     },
     {
-        "duration": "106.0",
-        "name": "v8.browsing_mobile/browse:news:toi"
-    },
-    {
         "duration": "55.0",
         "name": "v8.browsing_mobile/browse:news:washingtonpost"
     },
     {
-        "duration": "27.0",
+        "duration": "30.0",
         "name": "v8.browsing_mobile/browse:search:amp:2018"
     },
     {
+        "duration": "26.0",
+        "name": "v8.browsing_mobile/browse:search:amp:sxg:2019"
+    },
+    {
         "duration": "65.0",
         "name": "v8.browsing_mobile/browse:shopping:amazon"
     },
     {
-        "duration": "32.0",
+        "duration": "33.0",
         "name": "v8.browsing_mobile/browse:shopping:lazada"
     },
     {
-        "duration": "73.0",
+        "duration": "71.0",
         "name": "v8.browsing_mobile/browse:social:facebook"
     },
     {
-        "duration": "92.0",
+        "duration": "112.0",
         "name": "v8.browsing_mobile/browse:social:facebook_infinite_scroll"
     },
     {
@@ -4340,31 +4112,27 @@
         "name": "v8.browsing_mobile/browse:social:facebook_infinite_scroll:2018"
     },
     {
-        "duration": "88.0",
+        "duration": "85.0",
         "name": "v8.browsing_mobile/browse:social:instagram"
     },
     {
-        "duration": "90.0",
+        "duration": "86.0",
         "name": "v8.browsing_mobile/browse:social:pinterest_infinite_scroll"
     },
     {
-        "duration": "94.0",
-        "name": "v8.browsing_mobile/browse:social:tumblr_infinite_scroll"
-    },
-    {
-        "duration": "88.0",
+        "duration": "85.0",
         "name": "v8.browsing_mobile/browse:social:tumblr_infinite_scroll:2018"
     },
     {
-        "duration": "52.0",
+        "duration": "55.0",
         "name": "v8.browsing_mobile/browse:social:twitter"
     },
     {
-        "duration": "68.0",
+        "duration": "66.0",
         "name": "v8.browsing_mobile/browse:tech:discourse_infinite_scroll"
     },
     {
-        "duration": "92.0",
+        "duration": "89.0",
         "name": "v8.browsing_mobile/browse:tech:discourse_infinite_scroll:2018"
     },
     {
@@ -4372,59 +4140,35 @@
         "name": "v8.browsing_mobile/browse:tools:maps"
     },
     {
-        "duration": "14.0",
-        "name": "wasm/AsmJsZenGarden"
-    },
-    {
-        "duration": "15.0",
-        "name": "wasm/WasmSpaceBuggy"
-    },
-    {
-        "duration": "14.0",
-        "name": "wasm/WasmStylizedRenderer"
-    },
-    {
-        "duration": "14.0",
-        "name": "wasm/WasmSunTemple"
-    },
-    {
         "duration": "21.0",
-        "name": "wasm/WasmTanks"
-    },
-    {
-        "duration": "14.0",
-        "name": "wasm/WasmZenGarden"
-    },
-    {
-        "duration": "17.0",
         "name": "webrtc/10s_datachannel_transfer"
     },
     {
-        "duration": "20.0",
+        "duration": "22.0",
         "name": "webrtc/canvas_capture_peer_connection"
     },
     {
-        "duration": "29.0",
+        "duration": "33.0",
         "name": "webrtc/codec_constraints_h264"
     },
     {
-        "duration": "29.0",
+        "duration": "31.0",
         "name": "webrtc/codec_constraints_vp8"
     },
     {
-        "duration": "29.0",
+        "duration": "31.0",
         "name": "webrtc/codec_constraints_vp9"
     },
     {
-        "duration": "18.0",
+        "duration": "21.0",
         "name": "webrtc/hd_local_stream_10s"
     },
     {
-        "duration": "31.0",
+        "duration": "32.0",
         "name": "webrtc/multiple_peerconnections"
     },
     {
-        "duration": "39.0",
+        "duration": "40.0",
         "name": "webrtc/pause_play_peerconnections"
     }
 ]
\ No newline at end of file
diff --git a/tools/perf/core/shard_maps/timing_data/android-pixel2_webview-perf_timing.json b/tools/perf/core/shard_maps/timing_data/android-pixel2_webview-perf_timing.json
index bd9f39f..1c0dea7 100644
--- a/tools/perf/core/shard_maps/timing_data/android-pixel2_webview-perf_timing.json
+++ b/tools/perf/core/shard_maps/timing_data/android-pixel2_webview-perf_timing.json
@@ -1,14 +1,14 @@
 [
     {
-        "duration": "32.0",
+        "duration": "27.0",
         "name": "blink_perf.accessibility/line-breaks.html"
     },
     {
-        "duration": "24.0",
+        "duration": "20.0",
         "name": "blink_perf.accessibility/textarea-append.html"
     },
     {
-        "duration": "16.0",
+        "duration": "17.0",
         "name": "blink_perf.bindings/append-child.html"
     },
     {
@@ -52,7 +52,7 @@
         "name": "blink_perf.bindings/get-element-by-id.html"
     },
     {
-        "duration": "10.0",
+        "duration": "11.0",
         "name": "blink_perf.bindings/get-elements-by-tag-name.html"
     },
     {
@@ -64,7 +64,7 @@
         "name": "blink_perf.bindings/id-setter.html"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "blink_perf.bindings/indexed-getter.html"
     },
     {
@@ -72,11 +72,11 @@
         "name": "blink_perf.bindings/insert-before.html"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "blink_perf.bindings/named-property-enumerator.html"
     },
     {
-        "duration": "18.0",
+        "duration": "19.0",
         "name": "blink_perf.bindings/node-list-access.html"
     },
     {
@@ -88,7 +88,7 @@
         "name": "blink_perf.bindings/post-message.html"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "blink_perf.bindings/sequence-conversion-array.html"
     },
     {
@@ -100,15 +100,15 @@
         "name": "blink_perf.bindings/serialize-array.html"
     },
     {
-        "duration": "5.0",
+        "duration": "6.0",
         "name": "blink_perf.bindings/serialize-long-string.html"
     },
     {
-        "duration": "8.0",
+        "duration": "9.0",
         "name": "blink_perf.bindings/serialize-map.html"
     },
     {
-        "duration": "5.0",
+        "duration": "6.0",
         "name": "blink_perf.bindings/serialize-nested-array.html"
     },
     {
@@ -120,11 +120,11 @@
         "name": "blink_perf.bindings/set-attribute.html"
     },
     {
-        "duration": "17.0",
+        "duration": "20.0",
         "name": "blink_perf.bindings/structured-clone-json-deserialize.html"
     },
     {
-        "duration": "17.0",
+        "duration": "20.0",
         "name": "blink_perf.bindings/structured-clone-json-serialize.html"
     },
     {
@@ -132,11 +132,11 @@
         "name": "blink_perf.bindings/typed-array-construct-from-array.html"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "blink_perf.bindings/typed-array-construct-from-same-type.html"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "blink_perf.bindings/typed-array-construct-from-typed.html"
     },
     {
@@ -156,19 +156,19 @@
         "name": "blink_perf.bindings/undefined-id-getter.html"
     },
     {
-        "duration": "6.0",
+        "duration": "5.0",
         "name": "blink_perf.bindings/worker-structured-clone-different-payloads.html"
     },
     {
-        "duration": "30.0",
+        "duration": "31.0",
         "name": "blink_perf.bindings/worker-structured-clone-json-from-worker.html"
     },
     {
-        "duration": "30.0",
+        "duration": "31.0",
         "name": "blink_perf.bindings/worker-structured-clone-json-roundtrip.html"
     },
     {
-        "duration": "30.0",
+        "duration": "31.0",
         "name": "blink_perf.bindings/worker-structured-clone-json-to-worker.html"
     },
     {
@@ -184,11 +184,11 @@
         "name": "blink_perf.bindings/worker-text-encoded-transferable-from-worker.html"
     },
     {
-        "duration": "63.0",
+        "duration": "64.0",
         "name": "blink_perf.bindings/worker-text-encoded-transferable-roundtrip.html"
     },
     {
-        "duration": "63.0",
+        "duration": "64.0",
         "name": "blink_perf.bindings/worker-text-encoded-transferable-to-worker.html"
     },
     {
@@ -204,7 +204,7 @@
         "name": "blink_perf.bindings/worker-transferable-to-worker.html"
     },
     {
-        "duration": "17.0",
+        "duration": "18.0",
         "name": "blink_perf.canvas/createImageBitmapFromImageData.html"
     },
     {
@@ -220,7 +220,7 @@
         "name": "blink_perf.canvas/docs-paper_RAF.html?RAF"
     },
     {
-        "duration": "12.0",
+        "duration": "13.0",
         "name": "blink_perf.canvas/docs-resume.html"
     },
     {
@@ -244,7 +244,7 @@
         "name": "blink_perf.canvas/draw-dynamic-canvas-2d-to-hw-accelerated-canvas-2d_RAF.html?RAF"
     },
     {
-        "duration": "12.0",
+        "duration": "13.0",
         "name": "blink_perf.canvas/draw-dynamic-webgl-to-hw-accelerated-canvas-2d.html"
     },
     {
@@ -252,7 +252,7 @@
         "name": "blink_perf.canvas/draw-dynamic-webgl-to-hw-accelerated-canvas-2d_RAF.html?RAF"
     },
     {
-        "duration": "6.0",
+        "duration": "5.0",
         "name": "blink_perf.canvas/draw-hw-accelerated-canvas-2d-to-sw-canvas-2d.html"
     },
     {
@@ -260,7 +260,7 @@
         "name": "blink_perf.canvas/draw-hw-accelerated-canvas-2d-to-sw-canvas-2d_RAF.html?RAF"
     },
     {
-        "duration": "5.0",
+        "duration": "6.0",
         "name": "blink_perf.canvas/draw-static-canvas-2d-to-hw-accelerated-canvas-2d.html"
     },
     {
@@ -276,7 +276,7 @@
         "name": "blink_perf.canvas/draw-static-webgl-to-hw-accelerated-canvas-2d_RAF.html?RAF"
     },
     {
-        "duration": "9.0",
+        "duration": "10.0",
         "name": "blink_perf.canvas/draw-video-to-hw-accelerated-canvas-2d_RAF.html?RAF"
     },
     {
@@ -284,19 +284,19 @@
         "name": "blink_perf.canvas/drawimage-not-pixelaligned.html"
     },
     {
-        "duration": "12.0",
+        "duration": "11.0",
         "name": "blink_perf.canvas/drawimage-not-pixelaligned_RAF.html?RAF"
     },
     {
-        "duration": "11.0",
+        "duration": "14.0",
         "name": "blink_perf.canvas/drawimage.html"
     },
     {
-        "duration": "11.0",
+        "duration": "13.0",
         "name": "blink_perf.canvas/drawimage_RAF.html?RAF"
     },
     {
-        "duration": "10.0",
+        "duration": "11.0",
         "name": "blink_perf.canvas/getImageData.html"
     },
     {
@@ -308,7 +308,7 @@
         "name": "blink_perf.canvas/getImageDataColorManaged_RAF.html?RAF"
     },
     {
-        "duration": "10.0",
+        "duration": "11.0",
         "name": "blink_perf.canvas/getImageData_RAF.html?RAF"
     },
     {
@@ -352,7 +352,7 @@
         "name": "blink_perf.canvas/toBlob_duration_jpeg_RAF.html?RAF"
     },
     {
-        "duration": "6.0",
+        "duration": "7.0",
         "name": "blink_perf.canvas/transferFromImageBitmap.html"
     },
     {
@@ -360,7 +360,7 @@
         "name": "blink_perf.canvas/transferFromImageBitmap_RAF.html?RAF"
     },
     {
-        "duration": "8.0",
+        "duration": "9.0",
         "name": "blink_perf.canvas/upload-canvas-2d-to-texture.html"
     },
     {
@@ -368,19 +368,19 @@
         "name": "blink_perf.canvas/upload-canvas-2d-to-texture_RAF.html?RAF"
     },
     {
-        "duration": "7.0",
+        "duration": "8.0",
         "name": "blink_perf.canvas/upload-video-to-sub-texture_RAF.html?RAF"
     },
     {
-        "duration": "10.0",
+        "duration": "11.0",
         "name": "blink_perf.canvas/upload-video-to-texture_RAF.html?RAF"
     },
     {
-        "duration": "8.0",
+        "duration": "9.0",
         "name": "blink_perf.canvas/upload-webgl-to-texture.html"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "blink_perf.canvas/upload-webgl-to-texture_RAF.html?RAF"
     },
     {
@@ -392,7 +392,7 @@
         "name": "blink_perf.css/CSSPropertySetterGetter.html"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "blink_perf.css/CSSPropertySetterGetterMethods.html"
     },
     {
@@ -412,63 +412,63 @@
         "name": "blink_perf.css/ChangeStyleElementSelector.html"
     },
     {
-        "duration": "10.0",
+        "duration": "9.0",
         "name": "blink_perf.css/ChangeStyleGrandChildElementSelector.html"
     },
     {
-        "duration": "10.0",
+        "duration": "9.0",
         "name": "blink_perf.css/ChangeStyleMultipleClassSelector.html"
     },
     {
-        "duration": "10.0",
+        "duration": "9.0",
         "name": "blink_perf.css/ChangeStyleMultipleQualifiedDataAttributesWithValuesSelector.html"
     },
     {
-        "duration": "10.0",
+        "duration": "9.0",
         "name": "blink_perf.css/ChangeStyleNestedPseudoSelector.html"
     },
     {
-        "duration": "10.0",
+        "duration": "9.0",
         "name": "blink_perf.css/ChangeStylePairOfNthChildSelector.html"
     },
     {
-        "duration": "11.0",
+        "duration": "9.0",
         "name": "blink_perf.css/ChangeStylePartialAttributeMatchingSelector.html"
     },
     {
-        "duration": "11.0",
+        "duration": "9.0",
         "name": "blink_perf.css/ChangeStyleQualifiedDataAttributeSelector.html"
     },
     {
-        "duration": "11.0",
+        "duration": "9.0",
         "name": "blink_perf.css/ChangeStyleQualifiedDataAttributeWithValueSelector.html"
     },
     {
-        "duration": "12.0",
+        "duration": "11.0",
         "name": "blink_perf.css/ChangeStyleShallowTree.html"
     },
     {
-        "duration": "11.0",
+        "duration": "9.0",
         "name": "blink_perf.css/ChangeStyleSingleClassSelector.html"
     },
     {
-        "duration": "11.0",
+        "duration": "9.0",
         "name": "blink_perf.css/ChangeStyleSingleNthChildSelector.html"
     },
     {
-        "duration": "12.0",
+        "duration": "10.0",
         "name": "blink_perf.css/ChangeStyleSinglePseudoSelector.html"
     },
     {
-        "duration": "12.0",
+        "duration": "10.0",
         "name": "blink_perf.css/ChangeStyleUniversalSelector.html"
     },
     {
-        "duration": "12.0",
+        "duration": "10.0",
         "name": "blink_perf.css/ChangeStyleUnqualifiedDataAttributeSelector.html"
     },
     {
-        "duration": "12.0",
+        "duration": "10.0",
         "name": "blink_perf.css/ChangeStyleUnqualifiedDataAttributeWithValueSelector.html"
     },
     {
@@ -480,7 +480,7 @@
         "name": "blink_perf.css/ClassInvalidation.html"
     },
     {
-        "duration": "9.0",
+        "duration": "8.0",
         "name": "blink_perf.css/CustomPropertiesCascade.html"
     },
     {
@@ -500,19 +500,19 @@
         "name": "blink_perf.css/FocusUpdate.html"
     },
     {
-        "duration": "12.0",
+        "duration": "10.0",
         "name": "blink_perf.css/LoadBootstrapBlog.html"
     },
     {
-        "duration": "12.0",
+        "duration": "10.0",
         "name": "blink_perf.css/LoadMaterializeStarterPage.html"
     },
     {
-        "duration": "12.0",
+        "duration": "11.0",
         "name": "blink_perf.css/LoadSemanticPageExample.html"
     },
     {
-        "duration": "12.0",
+        "duration": "11.0",
         "name": "blink_perf.css/PseudoClassSelectors.html"
     },
     {
@@ -520,15 +520,15 @@
         "name": "blink_perf.css/SelectorCountScaling.html"
     },
     {
-        "duration": "33.0",
+        "duration": "36.0",
         "name": "blink_perf.dom/custom-element-default-style-with-shadow.html"
     },
     {
-        "duration": "24.0",
+        "duration": "26.0",
         "name": "blink_perf.dom/custom-element-default-style.html"
     },
     {
-        "duration": "71.0",
+        "duration": "16.0",
         "name": "blink_perf.dom/long-sibling-list.html"
     },
     {
@@ -544,7 +544,7 @@
         "name": "blink_perf.dom/modify-element-title.html"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "blink_perf.dom/select-multiple-add.html"
     },
     {
@@ -556,7 +556,7 @@
         "name": "blink_perf.dom/select-single-remove.html"
     },
     {
-        "duration": "22.0",
+        "duration": "21.0",
         "name": "blink_perf.events/EventsDispatching.html"
     },
     {
@@ -568,7 +568,7 @@
         "name": "blink_perf.events/EventsDispatchingInDeeplyNestedV1ShadowTrees.html"
     },
     {
-        "duration": "21.0",
+        "duration": "22.0",
         "name": "blink_perf.events/EventsDispatchingInV0ShadowTrees.html"
     },
     {
@@ -576,7 +576,7 @@
         "name": "blink_perf.events/EventsDispatchingInV1ShadowTrees.html"
     },
     {
-        "duration": "23.0",
+        "duration": "27.0",
         "name": "blink_perf.events/hit-test-lots-of-layers.html"
     },
     {
@@ -584,35 +584,47 @@
         "name": "blink_perf.events/is-input-pending-all-events.html"
     },
     {
-        "duration": "13.0",
+        "duration": "14.0",
         "name": "blink_perf.events/is-input-pending-default-events.html"
     },
     {
-        "duration": "52.0",
+        "duration": "51.0",
         "name": "blink_perf.image_decoder/decode-gif.html"
     },
     {
-        "duration": "23.0",
-        "name": "blink_perf.image_decoder/decode-jpeg.html"
+        "duration": "21.0",
+        "name": "blink_perf.image_decoder/decode-jpeg-h1v1.html"
     },
     {
-        "duration": "58.0",
+        "duration": "20.0",
+        "name": "blink_perf.image_decoder/decode-jpeg-h1v2.html"
+    },
+    {
+        "duration": "20.0",
+        "name": "blink_perf.image_decoder/decode-jpeg-h2v1.html"
+    },
+    {
+        "duration": "19.0",
+        "name": "blink_perf.image_decoder/decode-jpeg-h2v2.html"
+    },
+    {
+        "duration": "52.0",
         "name": "blink_perf.image_decoder/decode-lossless-webp.html"
     },
     {
-        "duration": "16.0",
+        "duration": "13.0",
         "name": "blink_perf.image_decoder/decode-lossy-webp.html"
     },
     {
-        "duration": "42.0",
+        "duration": "34.0",
         "name": "blink_perf.image_decoder/decode-png-palette-opaque.html"
     },
     {
-        "duration": "29.0",
+        "duration": "20.0",
         "name": "blink_perf.image_decoder/decode-png-palette.html"
     },
     {
-        "duration": "68.0",
+        "duration": "57.0",
         "name": "blink_perf.image_decoder/decode-png.html"
     },
     {
@@ -620,7 +632,7 @@
         "name": "blink_perf.layout/ArabicLineLayout.html"
     },
     {
-        "duration": "5.0",
+        "duration": "6.0",
         "name": "blink_perf.layout/Shapes/MultipleShapes.html"
     },
     {
@@ -628,15 +640,19 @@
         "name": "blink_perf.layout/SimpleTextPathLineLayout.html"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "blink_perf.layout/add-remove-inline-floats.html"
     },
     {
-        "duration": "11.0",
+        "duration": "6.0",
+        "name": "blink_perf.layout/animate-abspos-deep.html"
+    },
+    {
+        "duration": "12.0",
         "name": "blink_perf.layout/attach-inlines-2.html"
     },
     {
-        "duration": "10.0",
+        "duration": "11.0",
         "name": "blink_perf.layout/attach-inlines.html"
     },
     {
@@ -644,15 +660,15 @@
         "name": "blink_perf.layout/auto-grid-lots-of-data.html"
     },
     {
-        "duration": "13.0",
+        "duration": "14.0",
         "name": "blink_perf.layout/change-text-css-contain.html"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "blink_perf.layout/chapter-reflow-once-random.html"
     },
     {
-        "duration": "14.0",
+        "duration": "10.0",
         "name": "blink_perf.layout/chapter-reflow-once.html"
     },
     {
@@ -660,7 +676,7 @@
         "name": "blink_perf.layout/chapter-reflow-thrice.html"
     },
     {
-        "duration": "12.0",
+        "duration": "11.0",
         "name": "blink_perf.layout/chapter-reflow-twice.html"
     },
     {
@@ -668,19 +684,15 @@
         "name": "blink_perf.layout/chapter-reflow.html"
     },
     {
-        "duration": "15.0",
+        "duration": "10.0",
         "name": "blink_perf.layout/character_fallback.html"
     },
     {
-        "duration": "5.0",
-        "name": "blink_perf.layout/character_fallback_aat.html"
-    },
-    {
-        "duration": "15.0",
+        "duration": "11.0",
         "name": "blink_perf.layout/contain-content-style-change.html"
     },
     {
-        "duration": "12.0",
+        "duration": "16.0",
         "name": "blink_perf.layout/fit-content-change-available-size-blocks.html"
     },
     {
@@ -704,11 +716,11 @@
         "name": "blink_perf.layout/flexbox-column-wrap.html"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "blink_perf.layout/flexbox-deeply-nested-column-flow.html"
     },
     {
-        "duration": "10.0",
+        "duration": "11.0",
         "name": "blink_perf.layout/flexbox-lots-of-data.html"
     },
     {
@@ -716,7 +728,7 @@
         "name": "blink_perf.layout/flexbox-row-nowrap.html"
     },
     {
-        "duration": "13.0",
+        "duration": "14.0",
         "name": "blink_perf.layout/flexbox-row-stretch-height-definite.html"
     },
     {
@@ -728,11 +740,11 @@
         "name": "blink_perf.layout/flexbox-with-stretch-layout.html"
     },
     {
-        "duration": "15.0",
+        "duration": "13.0",
         "name": "blink_perf.layout/floats_100_100.html"
     },
     {
-        "duration": "15.0",
+        "duration": "13.0",
         "name": "blink_perf.layout/floats_100_100_nested.html"
     },
     {
@@ -740,11 +752,11 @@
         "name": "blink_perf.layout/floats_10_1000.html"
     },
     {
-        "duration": "9.0",
+        "duration": "8.0",
         "name": "blink_perf.layout/floats_20_100.html"
     },
     {
-        "duration": "10.0",
+        "duration": "9.0",
         "name": "blink_perf.layout/floats_20_100_nested.html"
     },
     {
@@ -756,11 +768,11 @@
         "name": "blink_perf.layout/floats_2_100_nested.html"
     },
     {
-        "duration": "10.0",
+        "duration": "8.0",
         "name": "blink_perf.layout/floats_50_100.html"
     },
     {
-        "duration": "10.0",
+        "duration": "8.0",
         "name": "blink_perf.layout/floats_50_100_nested.html"
     },
     {
@@ -768,11 +780,11 @@
         "name": "blink_perf.layout/hindi-line-layout.html"
     },
     {
-        "duration": "6.0",
+        "duration": "9.0",
         "name": "blink_perf.layout/japanese-kokoro-insert.html"
     },
     {
-        "duration": "14.0",
+        "duration": "15.0",
         "name": "blink_perf.layout/large-grid.html"
     },
     {
@@ -780,47 +792,43 @@
         "name": "blink_perf.layout/large-spanning-grid-item.html"
     },
     {
-        "duration": "15.0",
+        "duration": "17.0",
         "name": "blink_perf.layout/large-table-with-collapsed-borders-and-colspans-wider-than-table.html"
     },
     {
-        "duration": "15.0",
+        "duration": "17.0",
         "name": "blink_perf.layout/large-table-with-collapsed-borders-and-colspans.html"
     },
     {
-        "duration": "15.0",
+        "duration": "17.0",
         "name": "blink_perf.layout/large-table-with-collapsed-borders-and-no-colspans.html"
     },
     {
-        "duration": "127.0",
+        "duration": "21.0",
         "name": "blink_perf.layout/latin-ebook-resize.html"
     },
     {
-        "duration": "19.0",
+        "duration": "13.0",
         "name": "blink_perf.layout/latin-ebook.html"
     },
     {
-        "duration": "6.0",
+        "duration": "7.0",
         "name": "blink_perf.layout/layers_overlap_2d.html"
     },
     {
-        "duration": "6.0",
+        "duration": "7.0",
         "name": "blink_perf.layout/layers_overlap_3d.html"
     },
     {
-        "duration": "6.0",
+        "duration": "157.0",
         "name": "blink_perf.layout/line-layout-fit-content-break-word.html"
     },
     {
-        "duration": "9.0",
-        "name": "blink_perf.layout/line-layout-fit-content.html"
-    },
-    {
-        "duration": "14.0",
+        "duration": "22.0",
         "name": "blink_perf.layout/line-layout-line-height.html"
     },
     {
-        "duration": "11.0",
+        "duration": "13.0",
         "name": "blink_perf.layout/line-layout-repeat-append-select.html"
     },
     {
@@ -828,23 +836,23 @@
         "name": "blink_perf.layout/line-layout-repeat-append.html"
     },
     {
-        "duration": "10.0",
+        "duration": "11.0",
         "name": "blink_perf.layout/line-layout.html"
     },
     {
-        "duration": "5.0",
+        "duration": "6.0",
         "name": "blink_perf.layout/long-line-nowrap-collapse.html"
     },
     {
-        "duration": "5.0",
+        "duration": "6.0",
         "name": "blink_perf.layout/long-line-nowrap-spans-collapse.html"
     },
     {
-        "duration": "9.0",
+        "duration": "16.0",
         "name": "blink_perf.layout/long-line-nowrap.html"
     },
     {
-        "duration": "10.0",
+        "duration": "11.0",
         "name": "blink_perf.layout/many-block-children-auto-inline-size.html"
     },
     {
@@ -852,15 +860,15 @@
         "name": "blink_perf.layout/many-block-children-fixed-inline-size.html"
     },
     {
-        "duration": "12.0",
+        "duration": "11.0",
         "name": "blink_perf.layout/multicol/deeply-nested-tables.html"
     },
     {
-        "duration": "10.0",
+        "duration": "11.0",
         "name": "blink_perf.layout/multicol/fixed-height-with-spanner-and-nested-tables.html"
     },
     {
-        "duration": "11.0",
+        "duration": "10.0",
         "name": "blink_perf.layout/multicol/lots-of-text-autofill.html"
     },
     {
@@ -868,7 +876,7 @@
         "name": "blink_perf.layout/multicol/lots-of-text-balanced-orphans-widows.html"
     },
     {
-        "duration": "10.0",
+        "duration": "11.0",
         "name": "blink_perf.layout/multicol/lots-of-text-balanced.html"
     },
     {
@@ -888,115 +896,111 @@
         "name": "blink_perf.layout/nested-grid.html"
     },
     {
-        "duration": "38.0",
+        "duration": "11.0",
         "name": "blink_perf.layout/nested-percent-height-tables.html"
     },
     {
-        "duration": "82.0",
+        "duration": "78.0",
         "name": "blink_perf.layout/subtree-detaching.html"
     },
     {
-        "duration": "7.0",
+        "duration": "9.0",
         "name": "blink_perf.layout/vertical-japanese-kokoro-insert.html"
     },
     {
-        "duration": "8.0",
+        "duration": "15.0",
         "name": "blink_perf.layout/word-break-break-all.html"
     },
     {
-        "duration": "8.0",
+        "duration": "15.0",
         "name": "blink_perf.layout/word-break-break-word.html"
     },
     {
-        "duration": "8.0",
+        "duration": "15.0",
         "name": "blink_perf.layout/word-wrap-break-word.html"
     },
     {
-        "duration": "21.0",
+        "duration": "17.0",
         "name": "blink_perf.owp_storage/blob-perf-files.html"
     },
     {
-        "duration": "16.0",
+        "duration": "12.0",
         "name": "blink_perf.owp_storage/blob-perf-ipc.html"
     },
     {
-        "duration": "14.0",
+        "duration": "11.0",
         "name": "blink_perf.owp_storage/blob-perf-shm.html"
     },
     {
-        "duration": "16.0",
+        "duration": "12.0",
         "name": "blink_perf.owp_storage/blob-perf-tiny.html"
     },
     {
-        "duration": "16.0",
+        "duration": "13.0",
         "name": "blink_perf.owp_storage/idb-load-docs.html"
     },
     {
-        "duration": "17.0",
+        "duration": "18.0",
         "name": "blink_perf.paint/appending-text.html"
     },
     {
-        "duration": "24.0",
+        "duration": "25.0",
         "name": "blink_perf.paint/color-changes.html"
     },
     {
-        "duration": "14.0",
+        "duration": "23.0",
         "name": "blink_perf.paint/complex-content-slow-scroll.html"
     },
     {
-        "duration": "14.0",
+        "duration": "22.0",
         "name": "blink_perf.paint/complex-iframe-filtered.html"
     },
     {
-        "duration": "46.0",
+        "duration": "51.0",
         "name": "blink_perf.paint/contain-update-layer-tree.html"
     },
     {
-        "duration": "17.0",
+        "duration": "28.0",
         "name": "blink_perf.paint/containment-resize.html"
     },
     {
-        "duration": "16.0",
+        "duration": "17.0",
         "name": "blink_perf.paint/fixed-and-many-layers-scroll.html"
     },
     {
-        "duration": "19.0",
+        "duration": "24.0",
         "name": "blink_perf.paint/large-table-background-change-with-invisible-collapsed-borders.html"
     },
     {
-        "duration": "16.0",
+        "duration": "18.0",
         "name": "blink_perf.paint/large-table-background-change-with-visible-collapsed-borders.html"
     },
     {
-        "duration": "20.0",
+        "duration": "25.0",
         "name": "blink_perf.paint/large-table-background-change-with-zero-width-collapsed-borders.html"
     },
     {
-        "duration": "16.0",
+        "duration": "18.0",
         "name": "blink_perf.paint/large-table-collapsed-border-change-with-backgrounds.html"
     },
     {
-        "duration": "19.0",
+        "duration": "22.0",
         "name": "blink_perf.paint/large-table-collapsed-border-change-with-text.html"
     },
     {
-        "duration": "14.0",
+        "duration": "16.0",
         "name": "blink_perf.paint/large-table-collapsed-border-change.html"
     },
     {
-        "duration": "19.0",
+        "duration": "21.0",
         "name": "blink_perf.paint/large-table-repaint.html"
     },
     {
-        "duration": "13.0",
+        "duration": "29.0",
         "name": "blink_perf.paint/move-text-with-mask.html"
     },
     {
-        "duration": "19.0",
-        "name": "blink_perf.paint/select-all-words.html"
-    },
-    {
-        "duration": "28.0",
+        "duration": "29.0",
         "name": "blink_perf.paint/transform-changes.html"
     },
     {
@@ -1004,7 +1008,7 @@
         "name": "blink_perf.parser/css-parser-yui.html"
     },
     {
-        "duration": "12.0",
+        "duration": "11.0",
         "name": "blink_perf.parser/html-parser-threaded.html"
     },
     {
@@ -1012,11 +1016,11 @@
         "name": "blink_perf.parser/html-parser.html"
     },
     {
-        "duration": "72.0",
+        "duration": "87.0",
         "name": "blink_perf.parser/html5-full-render.html"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "blink_perf.parser/iframe-append-remove.html"
     },
     {
@@ -1024,7 +1028,7 @@
         "name": "blink_perf.parser/innerHTML-setter-siblings.html"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "blink_perf.parser/innerHTML-setter.html"
     },
     {
@@ -1036,7 +1040,7 @@
         "name": "blink_perf.parser/query-selector-all-attribute.html"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "blink_perf.parser/query-selector-all-class-deep.html"
     },
     {
@@ -1044,7 +1048,7 @@
         "name": "blink_perf.parser/query-selector-all-class-first.html"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "blink_perf.parser/query-selector-all-class-last.html"
     },
     {
@@ -1052,7 +1056,7 @@
         "name": "blink_perf.parser/query-selector-all-class.html"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "blink_perf.parser/query-selector-all-deep.html"
     },
     {
@@ -1060,7 +1064,7 @@
         "name": "blink_perf.parser/query-selector-all-first.html"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "blink_perf.parser/query-selector-all-id-deep.html"
     },
     {
@@ -1068,7 +1072,7 @@
         "name": "blink_perf.parser/query-selector-all-id-first.html"
     },
     {
-        "duration": "12.0",
+        "duration": "13.0",
         "name": "blink_perf.parser/query-selector-all-id-last.html"
     },
     {
@@ -1112,55 +1116,55 @@
         "name": "blink_perf.parser/url-parser.html"
     },
     {
-        "duration": "10.0",
+        "duration": "11.0",
         "name": "blink_perf.parser/xml-parser.html"
     },
     {
-        "duration": "12.0",
+        "duration": "11.0",
         "name": "blink_perf.shadow_dom/declarative-api.html"
     },
     {
-        "duration": "6.0",
+        "duration": "5.0",
         "name": "blink_perf.shadow_dom/imperative-api-appendchild.html"
     },
     {
-        "duration": "6.0",
+        "duration": "5.0",
         "name": "blink_perf.shadow_dom/imperative-api-assign.html"
     },
     {
-        "duration": "6.0",
+        "duration": "5.0",
         "name": "blink_perf.shadow_dom/imperative-api-assigned-elements.html"
     },
     {
-        "duration": "6.0",
+        "duration": "5.0",
         "name": "blink_perf.shadow_dom/imperative-api-assigned-slot.html"
     },
     {
-        "duration": "6.0",
+        "duration": "5.0",
         "name": "blink_perf.shadow_dom/imperative-api-custom-detail-summary-large.html"
     },
     {
-        "duration": "6.0",
+        "duration": "5.0",
         "name": "blink_perf.shadow_dom/imperative-api-custom-detail-summary.html"
     },
     {
-        "duration": "6.0",
+        "duration": "5.0",
         "name": "blink_perf.shadow_dom/imperative-api-detail-summary-large.html"
     },
     {
-        "duration": "6.0",
+        "duration": "5.0",
         "name": "blink_perf.shadow_dom/imperative-api-detail-summary.html"
     },
     {
-        "duration": "6.0",
+        "duration": "5.0",
         "name": "blink_perf.shadow_dom/imperative-api-insertbefore.html"
     },
     {
-        "duration": "6.0",
+        "duration": "5.0",
         "name": "blink_perf.shadow_dom/imperative-api.html"
     },
     {
-        "duration": "7.0",
+        "duration": "6.0",
         "name": "blink_perf.shadow_dom/shadow-style-share-attr-selectors.html"
     },
     {
@@ -1172,7 +1176,7 @@
         "name": "blink_perf.shadow_dom/shadow-style-share-with-distribution.html"
     },
     {
-        "duration": "6.0",
+        "duration": "5.0",
         "name": "blink_perf.shadow_dom/shadow-style-share.html"
     },
     {
@@ -1188,11 +1192,11 @@
         "name": "blink_perf.shadow_dom/v0-changing-classname-without-shadow-dom.html"
     },
     {
-        "duration": "9.0",
+        "duration": "11.0",
         "name": "blink_perf.shadow_dom/v0-changing-select-with-shadow-dom.html"
     },
     {
-        "duration": "9.0",
+        "duration": "12.0",
         "name": "blink_perf.shadow_dom/v0-changing-select-without-shadow-dom.html"
     },
     {
@@ -1200,11 +1204,11 @@
         "name": "blink_perf.shadow_dom/v0-content-reprojection.html"
     },
     {
-        "duration": "6.0",
+        "duration": "5.0",
         "name": "blink_perf.shadow_dom/v0-large-distribution-without-layout.html"
     },
     {
-        "duration": "6.0",
+        "duration": "5.0",
         "name": "blink_perf.shadow_dom/v0-multiple-insertion-points.html"
     },
     {
@@ -1212,19 +1216,19 @@
         "name": "blink_perf.shadow_dom/v0-shadow-reprojection.html"
     },
     {
-        "duration": "6.0",
+        "duration": "5.0",
         "name": "blink_perf.shadow_dom/v0-small-distribution-with-layout.html"
     },
     {
-        "duration": "14.0",
+        "duration": "13.0",
         "name": "blink_perf.shadow_dom/v1-distribution-disconnected-and-reconnected.html"
     },
     {
-        "duration": "6.0",
+        "duration": "5.0",
         "name": "blink_perf.shadow_dom/v1-distribution.html"
     },
     {
-        "duration": "6.0",
+        "duration": "5.0",
         "name": "blink_perf.shadow_dom/v1-host-child-append.html"
     },
     {
@@ -1232,7 +1236,7 @@
         "name": "blink_perf.shadow_dom/v1-large-deep-distribution.html"
     },
     {
-        "duration": "39.0",
+        "duration": "41.0",
         "name": "blink_perf.shadow_dom/v1-large-deep-layout.html"
     },
     {
@@ -1240,7 +1244,7 @@
         "name": "blink_perf.shadow_dom/v1-large-shallow-distribution.html"
     },
     {
-        "duration": "6.0",
+        "duration": "5.0",
         "name": "blink_perf.shadow_dom/v1-large-shallow-layout.html"
     },
     {
@@ -1256,7 +1260,7 @@
         "name": "blink_perf.shadow_dom/v1-mutate-deep-tree-then-slot-flatten.html"
     },
     {
-        "duration": "6.0",
+        "duration": "5.0",
         "name": "blink_perf.shadow_dom/v1-mutate-shallow-tree-then-re-layout.html"
     },
     {
@@ -1288,7 +1292,7 @@
         "name": "blink_perf.shadow_dom/v1-small-shallow-layout.html"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "blink_perf.svg/AzLizardBenjiPark.html"
     },
     {
@@ -1296,7 +1300,7 @@
         "name": "blink_perf.svg/Bamboo.html"
     },
     {
-        "duration": "6.0",
+        "duration": "12.0",
         "name": "blink_perf.svg/Cactus.html"
     },
     {
@@ -1304,7 +1308,7 @@
         "name": "blink_perf.svg/Cowboy.html"
     },
     {
-        "duration": "5.0",
+        "duration": "6.0",
         "name": "blink_perf.svg/CrawFishGanson.html"
     },
     {
@@ -1344,7 +1348,7 @@
         "name": "blink_perf.svg/HereGear.html"
     },
     {
-        "duration": "8.0",
+        "duration": "9.0",
         "name": "blink_perf.svg/MtSaintHelens.html"
     },
     {
@@ -1352,7 +1356,7 @@
         "name": "blink_perf.svg/Samurai.html"
     },
     {
-        "duration": "82.0",
+        "duration": "65.0",
         "name": "blink_perf.svg/SierpinskiCarpet.html"
     },
     {
@@ -1364,15 +1368,15 @@
         "name": "blink_perf.svg/SvgHitTesting.html"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "blink_perf.svg/SvgNestedUse.html"
     },
     {
-        "duration": "5.0",
+        "duration": "6.0",
         "name": "blink_perf.svg/UnderTheSee.html"
     },
     {
-        "duration": "6.0",
+        "duration": "7.0",
         "name": "blink_perf.svg/WorldIso.html"
     },
     {
@@ -1380,11 +1384,11 @@
         "name": "blink_perf.svg/Worldcup.html"
     },
     {
-        "duration": "40.0",
+        "duration": "41.0",
         "name": "dromaeo/http://dromaeo.com?dom-attr"
     },
     {
-        "duration": "37.0",
+        "duration": "36.0",
         "name": "dromaeo/http://dromaeo.com?dom-modify"
     },
     {
@@ -1392,11 +1396,11 @@
         "name": "dromaeo/http://dromaeo.com?dom-query"
     },
     {
-        "duration": "32.0",
+        "duration": "31.0",
         "name": "dromaeo/http://dromaeo.com?dom-traverse"
     },
     {
-        "duration": "9.0",
+        "duration": "11.0",
         "name": "dummy_benchmark.noisy_benchmark_1/dummy_page.html"
     },
     {
@@ -1404,7 +1408,7 @@
         "name": "dummy_benchmark.stable_benchmark_1/dummy_page.html"
     },
     {
-        "duration": "280.0",
+        "duration": "279.0",
         "name": "jetstream/http://browserbench.org/JetStream/"
     },
     {
@@ -1412,11 +1416,11 @@
         "name": "kraken/http://krakenbenchmark.mozilla.org/kraken-1.1/driver.html"
     },
     {
-        "duration": "10.0",
+        "duration": "9.0",
         "name": "loading.mobile/58Pic"
     },
     {
-        "duration": "42.0",
+        "duration": "53.0",
         "name": "loading.mobile/58Pic_3g"
     },
     {
@@ -1424,7 +1428,7 @@
         "name": "loading.mobile/Amazon"
     },
     {
-        "duration": "73.0",
+        "duration": "110.0",
         "name": "loading.mobile/Amazon_3g"
     },
     {
@@ -1432,11 +1436,11 @@
         "name": "loading.mobile/BOLNoticias"
     },
     {
-        "duration": "11.0",
+        "duration": "9.0",
         "name": "loading.mobile/Baidu"
     },
     {
-        "duration": "69.0",
+        "duration": "85.0",
         "name": "loading.mobile/Baidu_3g"
     },
     {
@@ -1444,11 +1448,11 @@
         "name": "loading.mobile/Bradesco"
     },
     {
-        "duration": "12.0",
+        "duration": "11.0",
         "name": "loading.mobile/Dailymotion"
     },
     {
-        "duration": "12.0",
+        "duration": "11.0",
         "name": "loading.mobile/Dawn"
     },
     {
@@ -1456,15 +1460,15 @@
         "name": "loading.mobile/DevOpera_cold"
     },
     {
-        "duration": "51.0",
+        "duration": "60.0",
         "name": "loading.mobile/DevOpera_cold_3g"
     },
     {
-        "duration": "15.0",
+        "duration": "14.0",
         "name": "loading.mobile/DevOpera_hot"
     },
     {
-        "duration": "54.0",
+        "duration": "60.0",
         "name": "loading.mobile/DevOpera_hot_3g"
     },
     {
@@ -1472,7 +1476,7 @@
         "name": "loading.mobile/DevOpera_warm"
     },
     {
-        "duration": "50.0",
+        "duration": "57.0",
         "name": "loading.mobile/DevOpera_warm_3g"
     },
     {
@@ -1480,7 +1484,7 @@
         "name": "loading.mobile/Dramaq"
     },
     {
-        "duration": "141.0",
+        "duration": "101.0",
         "name": "loading.mobile/Dramaq_3g"
     },
     {
@@ -1488,7 +1492,7 @@
         "name": "loading.mobile/EnquiryIndianRail"
     },
     {
-        "duration": "36.0",
+        "duration": "50.0",
         "name": "loading.mobile/EnquiryIndianRail_3g"
     },
     {
@@ -1500,11 +1504,11 @@
         "name": "loading.mobile/FlipBoard_cold"
     },
     {
-        "duration": "15.0",
+        "duration": "14.0",
         "name": "loading.mobile/FlipBoard_hot"
     },
     {
-        "duration": "26.0",
+        "duration": "27.0",
         "name": "loading.mobile/FlipBoard_hot_3g"
     },
     {
@@ -1512,7 +1516,7 @@
         "name": "loading.mobile/FlipBoard_warm"
     },
     {
-        "duration": "13.0",
+        "duration": "12.0",
         "name": "loading.mobile/FlipKart_cold"
     },
     {
@@ -1520,7 +1524,7 @@
         "name": "loading.mobile/FlipKart_hot"
     },
     {
-        "duration": "21.0",
+        "duration": "20.0",
         "name": "loading.mobile/FlipKart_hot_3g"
     },
     {
@@ -1532,11 +1536,11 @@
         "name": "loading.mobile/FranceTVInfo"
     },
     {
-        "duration": "71.0",
+        "duration": "83.0",
         "name": "loading.mobile/FranceTVInfo_3g"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "loading.mobile/GSShop"
     },
     {
@@ -1552,7 +1556,7 @@
         "name": "loading.mobile/GoogleIndonesia"
     },
     {
-        "duration": "12.0",
+        "duration": "13.0",
         "name": "loading.mobile/GoogleRedirectToGoogleJapan"
     },
     {
@@ -1568,7 +1572,7 @@
         "name": "loading.mobile/Kaskus"
     },
     {
-        "duration": "15.0",
+        "duration": "9.0",
         "name": "loading.mobile/LocalMoxie"
     },
     {
@@ -1576,7 +1580,7 @@
         "name": "loading.mobile/Locanto"
     },
     {
-        "duration": "29.0",
+        "duration": "33.0",
         "name": "loading.mobile/Locanto_3g"
     },
     {
@@ -1584,11 +1588,11 @@
         "name": "loading.mobile/OLX"
     },
     {
-        "duration": "12.0",
+        "duration": "8.0",
         "name": "loading.mobile/QQNews"
     },
     {
-        "duration": "80.0",
+        "duration": "109.0",
         "name": "loading.mobile/QQNews_3g"
     },
     {
@@ -1596,7 +1600,7 @@
         "name": "loading.mobile/SlideShare"
     },
     {
-        "duration": "65.0",
+        "duration": "95.0",
         "name": "loading.mobile/SlideShare_3g"
     },
     {
@@ -1604,7 +1608,7 @@
         "name": "loading.mobile/Suumo_cold"
     },
     {
-        "duration": "14.0",
+        "duration": "15.0",
         "name": "loading.mobile/Suumo_cold_3g"
     },
     {
@@ -1632,7 +1636,7 @@
         "name": "loading.mobile/TheStar"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "loading.mobile/TribunNews"
     },
     {
@@ -1640,7 +1644,7 @@
         "name": "loading.mobile/Twitter"
     },
     {
-        "duration": "37.0",
+        "duration": "55.0",
         "name": "loading.mobile/Twitter_3g"
     },
     {
@@ -1652,11 +1656,11 @@
         "name": "loading.mobile/Wikipedia"
     },
     {
-        "duration": "59.0",
+        "duration": "84.0",
         "name": "loading.mobile/Wikipedia_3g"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "loading.mobile/YahooNews"
     },
     {
@@ -1680,11 +1684,11 @@
         "name": "memory.top_10_mobile/after_http_search_yahoo_com_search__ylt_p_google"
     },
     {
-        "duration": "16.0",
+        "duration": "15.0",
         "name": "memory.top_10_mobile/after_http_www_amazon_com_gp_aw_s_k_nexus"
     },
     {
-        "duration": "15.0",
+        "duration": "22.0",
         "name": "memory.top_10_mobile/after_http_www_baidu_com_s_word_google"
     },
     {
@@ -1708,7 +1712,7 @@
         "name": "memory.top_10_mobile/http_en_m_wikipedia_org_wiki_Science"
     },
     {
-        "duration": "19.0",
+        "duration": "18.0",
         "name": "memory.top_10_mobile/http_m_intl_taobao_com_group_purchase_html"
     },
     {
@@ -1720,11 +1724,11 @@
         "name": "memory.top_10_mobile/http_search_yahoo_com_search__ylt_p_google"
     },
     {
-        "duration": "20.0",
+        "duration": "19.0",
         "name": "memory.top_10_mobile/http_www_amazon_com_gp_aw_s_k_nexus"
     },
     {
-        "duration": "21.0",
+        "duration": "20.0",
         "name": "memory.top_10_mobile/http_www_baidu_com_s_word_google"
     },
     {
@@ -1740,11 +1744,11 @@
         "name": "memory.top_10_mobile/https_mobile_twitter_com_justinbieber_skip_interstitial_true"
     },
     {
-        "duration": "20.0",
+        "duration": "16.0",
         "name": "memory.top_10_mobile/https_www_google_co_uk_hl_en_q_science"
     },
     {
-        "duration": "59.0",
+        "duration": "58.0",
         "name": "octane/http://chromium.github.io/octane/index.html?auto=1"
     },
     {
@@ -1752,15 +1756,15 @@
         "name": "power.typical_10_mobile/http://de.m.wikipedia.org/wiki/K%C3%B6lner_Dom"
     },
     {
-        "duration": "67.0",
+        "duration": "65.0",
         "name": "power.typical_10_mobile/http://m.chiebukuro.yahoo.co.jp/detail/q10136829180"
     },
     {
-        "duration": "58.0",
+        "duration": "59.0",
         "name": "power.typical_10_mobile/http://m.ebay.com/itm/351157205404"
     },
     {
-        "duration": "67.0",
+        "duration": "66.0",
         "name": "power.typical_10_mobile/http://m.facebook.com/barackobama"
     },
     {
@@ -1768,11 +1772,11 @@
         "name": "power.typical_10_mobile/http://m.huffpost.com/us/entry/6004486"
     },
     {
-        "duration": "63.0",
+        "duration": "64.0",
         "name": "power.typical_10_mobile/http://m.ynet.co.il"
     },
     {
-        "duration": "63.0",
+        "duration": "64.0",
         "name": "power.typical_10_mobile/http://siriuslymeg.tumblr.com/"
     },
     {
@@ -1784,7 +1788,7 @@
         "name": "power.typical_10_mobile/http://www.cnn.com/2014/03/31/showbiz/tv/himym-finale/index.html"
     },
     {
-        "duration": "62.0",
+        "duration": "63.0",
         "name": "power.typical_10_mobile/http://www.rg.ru/2014/10/21/cska-site.html"
     },
     {
@@ -1792,19 +1796,19 @@
         "name": "power.typical_10_mobile/https://en.wikipedia.org/wiki/File:Rotating_earth_(large).gif"
     },
     {
-        "duration": "16.0",
+        "duration": "17.0",
         "name": "rasterize_and_record_micro.partial_invalidation/800_relpos_divs.html"
     },
     {
-        "duration": "26.0",
+        "duration": "27.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/amazon.html"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/blogger.html"
     },
     {
-        "duration": "22.0",
+        "duration": "23.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/booking.html"
     },
     {
@@ -1816,15 +1820,15 @@
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/ebay.html"
     },
     {
-        "duration": "24.0",
+        "duration": "26.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/espn.html"
     },
     {
-        "duration": "21.0",
+        "duration": "22.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/facebook.html"
     },
     {
-        "duration": "36.0",
+        "duration": "37.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/gmail.html"
     },
     {
@@ -1832,7 +1836,7 @@
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/google.html"
     },
     {
-        "duration": "27.0",
+        "duration": "28.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/googlecalendar.html"
     },
     {
@@ -1840,15 +1844,15 @@
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/googledocs.html"
     },
     {
-        "duration": "24.0",
+        "duration": "25.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/googleimagesearch.html"
     },
     {
-        "duration": "22.0",
+        "duration": "23.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/googleplus.html"
     },
     {
-        "duration": "20.0",
+        "duration": "21.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/linkedin.html"
     },
     {
@@ -1864,7 +1868,7 @@
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/twitter.html"
     },
     {
-        "duration": "14.0",
+        "duration": "15.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/weather.html"
     },
     {
@@ -1876,11 +1880,11 @@
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/yahooanswers.html"
     },
     {
-        "duration": "64.0",
+        "duration": "63.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/yahoogames.html"
     },
     {
-        "duration": "87.0",
+        "duration": "88.0",
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/yahoosports.html"
     },
     {
@@ -1888,7 +1892,7 @@
         "name": "rasterize_and_record_micro.top_25/file://static_top_25/youtube.html"
     },
     {
-        "duration": "28.0",
+        "duration": "21.0",
         "name": "rendering.mobile/accu_weather_2018"
     },
     {
@@ -1896,7 +1900,7 @@
         "name": "rendering.mobile/accu_weather_mobile_pinch_2018"
     },
     {
-        "duration": "19.0",
+        "duration": "16.0",
         "name": "rendering.mobile/amazon_2018"
     },
     {
@@ -1904,27 +1908,27 @@
         "name": "rendering.mobile/amazon_mobile_2018"
     },
     {
-        "duration": "24.0",
+        "duration": "20.0",
         "name": "rendering.mobile/analog_clock_svg"
     },
     {
-        "duration": "21.0",
+        "duration": "20.0",
         "name": "rendering.mobile/androidpolice_mobile_2018"
     },
     {
-        "duration": "16.0",
+        "duration": "18.0",
         "name": "rendering.mobile/animometer_webgl"
     },
     {
-        "duration": "24.0",
+        "duration": "20.0",
         "name": "rendering.mobile/animometer_webgl_attrib_arrays"
     },
     {
-        "duration": "27.0",
+        "duration": "22.0",
         "name": "rendering.mobile/animometer_webgl_multi_draw"
     },
     {
-        "duration": "24.0",
+        "duration": "28.0",
         "name": "rendering.mobile/aquarium"
     },
     {
@@ -1932,11 +1936,11 @@
         "name": "rendering.mobile/background_color_animation"
     },
     {
-        "duration": "39.0",
+        "duration": "26.0",
         "name": "rendering.mobile/background_color_animation_with_gradient"
     },
     {
-        "duration": "13.0",
+        "duration": "12.0",
         "name": "rendering.mobile/baidu_mobile_2018"
     },
     {
@@ -1964,15 +1968,15 @@
         "name": "rendering.mobile/balls_javascript_css"
     },
     {
-        "duration": "21.0",
+        "duration": "20.0",
         "name": "rendering.mobile/balls_svg_animations"
     },
     {
-        "duration": "21.0",
+        "duration": "20.0",
         "name": "rendering.mobile/basic_stream"
     },
     {
-        "duration": "16.0",
+        "duration": "26.0",
         "name": "rendering.mobile/bing_mobile_2018"
     },
     {
@@ -1980,7 +1984,7 @@
         "name": "rendering.mobile/blob"
     },
     {
-        "duration": "13.0",
+        "duration": "12.0",
         "name": "rendering.mobile/blogspot_2018"
     },
     {
@@ -1988,7 +1992,7 @@
         "name": "rendering.mobile/blogspot_mobile_2018"
     },
     {
-        "duration": "15.0",
+        "duration": "16.0",
         "name": "rendering.mobile/blur_rotating_background"
     },
     {
@@ -1996,7 +2000,7 @@
         "name": "rendering.mobile/boingboing_mobile_2018"
     },
     {
-        "duration": "15.0",
+        "duration": "13.0",
         "name": "rendering.mobile/booking.com_2018"
     },
     {
@@ -2024,7 +2028,7 @@
         "name": "rendering.mobile/bouncing_svg_images"
     },
     {
-        "duration": "18.0",
+        "duration": "19.0",
         "name": "rendering.mobile/camera_to_webgl"
     },
     {
@@ -2044,15 +2048,15 @@
         "name": "rendering.mobile/canvas_font_cycler"
     },
     {
-        "duration": "12.0",
+        "duration": "13.0",
         "name": "rendering.mobile/canvas_lines"
     },
     {
-        "duration": "12.0",
+        "duration": "13.0",
         "name": "rendering.mobile/canvas_to_blob"
     },
     {
-        "duration": "19.0",
+        "duration": "22.0",
         "name": "rendering.mobile/capitolvolkswagen_mobile_2018"
     },
     {
@@ -2084,7 +2088,7 @@
         "name": "rendering.mobile/cc_poster_circle"
     },
     {
-        "duration": "15.0",
+        "duration": "14.0",
         "name": "rendering.mobile/cc_scroll_text_only"
     },
     {
@@ -2092,23 +2096,19 @@
         "name": "rendering.mobile/chip_tune"
     },
     {
-        "duration": "16.0",
+        "duration": "13.0",
         "name": "rendering.mobile/cnn_2018"
     },
     {
-        "duration": "16.0",
+        "duration": "22.0",
         "name": "rendering.mobile/cnn_article_mobile_2018"
     },
     {
-        "duration": "13.0",
+        "duration": "16.0",
         "name": "rendering.mobile/cnn_mobile_2018"
     },
     {
-        "duration": "17.0",
-        "name": "rendering.mobile/cnn_mobile_pinch_2018"
-    },
-    {
-        "duration": "16.0",
+        "duration": "18.0",
         "name": "rendering.mobile/cnn_pathological_2018"
     },
     {
@@ -2124,7 +2124,7 @@
         "name": "rendering.mobile/crafty_mind"
     },
     {
-        "duration": "20.0",
+        "duration": "19.0",
         "name": "rendering.mobile/css_animations_many_keyframes"
     },
     {
@@ -2156,7 +2156,7 @@
         "name": "rendering.mobile/css_animations_staggered_new_element"
     },
     {
-        "duration": "20.0",
+        "duration": "19.0",
         "name": "rendering.mobile/css_animations_staggered_style_element"
     },
     {
@@ -2168,11 +2168,11 @@
         "name": "rendering.mobile/css_animations_triggered_inline_style"
     },
     {
-        "duration": "22.0",
+        "duration": "21.0",
         "name": "rendering.mobile/css_animations_triggered_new_element"
     },
     {
-        "duration": "19.0",
+        "duration": "18.0",
         "name": "rendering.mobile/css_animations_triggered_style_element"
     },
     {
@@ -2240,11 +2240,11 @@
         "name": "rendering.mobile/css_transitions_updating_class"
     },
     {
-        "duration": "19.0",
+        "duration": "18.0",
         "name": "rendering.mobile/css_value_type_color"
     },
     {
-        "duration": "24.0",
+        "duration": "21.0",
         "name": "rendering.mobile/css_value_type_filter"
     },
     {
@@ -2264,7 +2264,7 @@
         "name": "rendering.mobile/css_value_type_path"
     },
     {
-        "duration": "28.0",
+        "duration": "21.0",
         "name": "rendering.mobile/css_value_type_shadow"
     },
     {
@@ -2276,47 +2276,47 @@
         "name": "rendering.mobile/css_value_type_transform_simple"
     },
     {
-        "duration": "17.0",
+        "duration": "19.0",
         "name": "rendering.mobile/deviantart_mobile_2018"
     },
     {
-        "duration": "14.0",
+        "duration": "16.0",
         "name": "rendering.mobile/digg_mobile_2018"
     },
     {
-        "duration": "16.0",
+        "duration": "17.0",
         "name": "rendering.mobile/dynamic_cube_map"
     },
     {
-        "duration": "15.0",
+        "duration": "16.0",
         "name": "rendering.mobile/earth"
     },
     {
-        "duration": "16.0",
+        "duration": "15.0",
         "name": "rendering.mobile/ebay_2018"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "rendering.mobile/ebay_mobile_2018"
     },
     {
-        "duration": "14.0",
+        "duration": "13.0",
         "name": "rendering.mobile/ebay_mobile_pinch_2018"
     },
     {
-        "duration": "24.0",
+        "duration": "22.0",
         "name": "rendering.mobile/ebay_scroll_2018"
     },
     {
-        "duration": "18.0",
+        "duration": "16.0",
         "name": "rendering.mobile/espn_2018"
     },
     {
-        "duration": "13.0",
+        "duration": "17.0",
         "name": "rendering.mobile/espn_mobile_2018"
     },
     {
-        "duration": "12.0",
+        "duration": "14.0",
         "name": "rendering.mobile/espn_pathological_2018"
     },
     {
@@ -2324,11 +2324,11 @@
         "name": "rendering.mobile/extra_large_texture_uploads"
     },
     {
-        "duration": "14.0",
+        "duration": "13.0",
         "name": "rendering.mobile/facebook_2018"
     },
     {
-        "duration": "19.0",
+        "duration": "21.0",
         "name": "rendering.mobile/facebook_mobile_2018"
     },
     {
@@ -2336,11 +2336,11 @@
         "name": "rendering.mobile/fill_shapes"
     },
     {
-        "duration": "20.0",
+        "duration": "19.0",
         "name": "rendering.mobile/filter_terrain_svg"
     },
     {
-        "duration": "23.0",
+        "duration": "22.0",
         "name": "rendering.mobile/flickr_scroll_2018"
     },
     {
@@ -2348,7 +2348,7 @@
         "name": "rendering.mobile/font_wipe"
     },
     {
-        "duration": "12.0",
+        "duration": "13.0",
         "name": "rendering.mobile/forecast.io_mobile_2018"
     },
     {
@@ -2360,15 +2360,15 @@
         "name": "rendering.mobile/gmail_2018"
     },
     {
-        "duration": "11.0",
+        "duration": "15.0",
         "name": "rendering.mobile/google_calendar_2018"
     },
     {
-        "duration": "21.0",
+        "duration": "18.0",
         "name": "rendering.mobile/google_docs_2018"
     },
     {
-        "duration": "17.0",
+        "duration": "15.0",
         "name": "rendering.mobile/google_image_search_2018"
     },
     {
@@ -2380,35 +2380,31 @@
         "name": "rendering.mobile/google_news_ios"
     },
     {
-        "duration": "11.0",
-        "name": "rendering.mobile/google_news_mobile_2018"
-    },
-    {
-        "duration": "20.0",
+        "duration": "19.0",
         "name": "rendering.mobile/google_plus_2018"
     },
     {
-        "duration": "18.0",
+        "duration": "23.0",
         "name": "rendering.mobile/google_plus_mobile_2018"
     },
     {
-        "duration": "14.0",
+        "duration": "16.0",
         "name": "rendering.mobile/google_search_mobile_pinch_2018"
     },
     {
-        "duration": "12.0",
+        "duration": "11.0",
         "name": "rendering.mobile/google_web_search_2018"
     },
     {
-        "duration": "17.0",
+        "duration": "15.0",
         "name": "rendering.mobile/google_web_search_mobile_2018"
     },
     {
-        "duration": "19.0",
+        "duration": "20.0",
         "name": "rendering.mobile/gsp.ro_mobile_2018"
     },
     {
-        "duration": "17.0",
+        "duration": "19.0",
         "name": "rendering.mobile/guardian_pathological_2018"
     },
     {
@@ -2416,15 +2412,15 @@
         "name": "rendering.mobile/guimark_vector_chart"
     },
     {
-        "duration": "16.0",
+        "duration": "15.0",
         "name": "rendering.mobile/gws_boogie_expansion"
     },
     {
-        "duration": "16.0",
+        "duration": "15.0",
         "name": "rendering.mobile/gws_google_expansion"
     },
     {
-        "duration": "13.0",
+        "duration": "15.0",
         "name": "rendering.mobile/hakim"
     },
     {
@@ -2432,7 +2428,7 @@
         "name": "rendering.mobile/horizontal_vertical_expansion"
     },
     {
-        "duration": "41.0",
+        "duration": "40.0",
         "name": "rendering.mobile/idle_power_animated_gif"
     },
     {
@@ -2456,19 +2452,19 @@
         "name": "rendering.mobile/idle_power_set_timetout"
     },
     {
-        "duration": "29.0",
+        "duration": "30.0",
         "name": "rendering.mobile/ie_chalkboard"
     },
     {
-        "duration": "25.0",
+        "duration": "23.0",
         "name": "rendering.mobile/ie_pirate_mark"
     },
     {
-        "duration": "20.0",
+        "duration": "25.0",
         "name": "rendering.mobile/infinite_scroll_element_n_layers_0"
     },
     {
-        "duration": "21.0",
+        "duration": "20.0",
         "name": "rendering.mobile/infinite_scroll_element_n_layers_75"
     },
     {
@@ -2476,11 +2472,11 @@
         "name": "rendering.mobile/infinite_scroll_element_n_layers_99"
     },
     {
-        "duration": "21.0",
+        "duration": "20.0",
         "name": "rendering.mobile/infinite_scroll_root_fixed_n_layers_0"
     },
     {
-        "duration": "21.0",
+        "duration": "20.0",
         "name": "rendering.mobile/infinite_scroll_root_fixed_n_layers_75"
     },
     {
@@ -2488,15 +2484,15 @@
         "name": "rendering.mobile/infinite_scroll_root_fixed_n_layers_99"
     },
     {
-        "duration": "21.0",
+        "duration": "20.0",
         "name": "rendering.mobile/infinite_scroll_root_n_layers_0"
     },
     {
-        "duration": "21.0",
+        "duration": "20.0",
         "name": "rendering.mobile/infinite_scroll_root_n_layers_75"
     },
     {
-        "duration": "21.0",
+        "duration": "20.0",
         "name": "rendering.mobile/infinite_scroll_root_n_layers_99"
     },
     {
@@ -2508,6 +2504,14 @@
         "name": "rendering.mobile/jarro_doverson"
     },
     {
+        "duration": "12.0",
+        "name": "rendering.mobile/jpeg_decoding_rgb_and_gpu_rasterization"
+    },
+    {
+        "duration": "12.0",
+        "name": "rendering.mobile/jpeg_decoding_yuv_and_gpu_rasterization"
+    },
+    {
         "duration": "26.0",
         "name": "rendering.mobile/js_full_screen_invalidation"
     },
@@ -2528,11 +2532,11 @@
         "name": "rendering.mobile/js_paint_plus_n_layers_0"
     },
     {
-        "duration": "23.0",
+        "duration": "22.0",
         "name": "rendering.mobile/js_paint_plus_n_layers_75"
     },
     {
-        "duration": "23.0",
+        "duration": "22.0",
         "name": "rendering.mobile/js_paint_plus_n_layers_99"
     },
     {
@@ -2552,23 +2556,23 @@
         "name": "rendering.mobile/large_texture_uploads"
     },
     {
-        "duration": "19.0",
+        "duration": "18.0",
         "name": "rendering.mobile/latimes_pathological_2018"
     },
     {
-        "duration": "16.0",
+        "duration": "17.0",
         "name": "rendering.mobile/linkedin_2018"
     },
     {
-        "duration": "37.0",
+        "duration": "39.0",
         "name": "rendering.mobile/linkedin_mobile_2018"
     },
     {
-        "duration": "31.0",
+        "duration": "33.0",
         "name": "rendering.mobile/linkedin_mobile_pinch_2018"
     },
     {
-        "duration": "29.0",
+        "duration": "30.0",
         "name": "rendering.mobile/linkedin_pathological_2018"
     },
     {
@@ -2576,7 +2580,7 @@
         "name": "rendering.mobile/list_animation_simple"
     },
     {
-        "duration": "19.0",
+        "duration": "18.0",
         "name": "rendering.mobile/list_recycle_transform"
     },
     {
@@ -2584,7 +2588,7 @@
         "name": "rendering.mobile/man_in_blue"
     },
     {
-        "duration": "23.0",
+        "duration": "21.0",
         "name": "rendering.mobile/many_images"
     },
     {
@@ -2596,7 +2600,7 @@
         "name": "rendering.mobile/mask_transition_animation"
     },
     {
-        "duration": "12.0",
+        "duration": "11.0",
         "name": "rendering.mobile/masonry"
     },
     {
@@ -2604,23 +2608,23 @@
         "name": "rendering.mobile/medium_texture_uploads"
     },
     {
-        "duration": "16.0",
+        "duration": "12.0",
         "name": "rendering.mobile/megi_dish"
     },
     {
-        "duration": "16.0",
+        "duration": "15.0",
         "name": "rendering.mobile/microsoft_asteroid_belt"
     },
     {
-        "duration": "14.0",
+        "duration": "13.0",
         "name": "rendering.mobile/microsoft_fish_ie_tank"
     },
     {
-        "duration": "19.0",
+        "duration": "18.0",
         "name": "rendering.mobile/microsoft_performance"
     },
     {
-        "duration": "14.0",
+        "duration": "13.0",
         "name": "rendering.mobile/microsoft_snow"
     },
     {
@@ -2632,7 +2636,7 @@
         "name": "rendering.mobile/microsoft_tweet_map"
     },
     {
-        "duration": "16.0",
+        "duration": "15.0",
         "name": "rendering.mobile/microsoft_video_city"
     },
     {
@@ -2644,23 +2648,23 @@
         "name": "rendering.mobile/mix_10k"
     },
     {
-        "duration": "23.0",
+        "duration": "21.0",
         "name": "rendering.mobile/mix_blend_mode_animation_difference"
     },
     {
-        "duration": "23.0",
+        "duration": "21.0",
         "name": "rendering.mobile/mix_blend_mode_animation_hue"
     },
     {
-        "duration": "24.0",
+        "duration": "19.0",
         "name": "rendering.mobile/mix_blend_mode_animation_propagating_isolation"
     },
     {
-        "duration": "22.0",
+        "duration": "20.0",
         "name": "rendering.mobile/mix_blend_mode_animation_screen"
     },
     {
-        "duration": "20.0",
+        "duration": "18.0",
         "name": "rendering.mobile/mlb_mobile_2018"
     },
     {
@@ -2680,87 +2684,87 @@
         "name": "rendering.mobile/motionmark_anim_design_15"
     },
     {
-        "duration": "18.0",
+        "duration": "17.0",
         "name": "rendering.mobile/motionmark_anim_focus_25"
     },
     {
-        "duration": "19.0",
+        "duration": "18.0",
         "name": "rendering.mobile/motionmark_anim_images_50"
     },
     {
-        "duration": "18.0",
+        "duration": "17.0",
         "name": "rendering.mobile/motionmark_anim_leaves_250"
     },
     {
-        "duration": "18.0",
+        "duration": "17.0",
         "name": "rendering.mobile/motionmark_anim_multiply_175"
     },
     {
-        "duration": "18.0",
+        "duration": "17.0",
         "name": "rendering.mobile/motionmark_anim_suits_125"
     },
     {
-        "duration": "18.0",
+        "duration": "17.0",
         "name": "rendering.mobile/motionmark_html_composited_transforms_125"
     },
     {
-        "duration": "19.0",
+        "duration": "17.0",
         "name": "rendering.mobile/motionmark_html_css_bouncing_blend_circles_25"
     },
     {
-        "duration": "19.0",
+        "duration": "17.0",
         "name": "rendering.mobile/motionmark_html_css_bouncing_circles_250"
     },
     {
-        "duration": "18.0",
+        "duration": "17.0",
         "name": "rendering.mobile/motionmark_html_css_bouncing_clipped_rects_100"
     },
     {
-        "duration": "18.0",
+        "duration": "17.0",
         "name": "rendering.mobile/motionmark_html_css_bouncing_filter_circles_15"
     },
     {
-        "duration": "18.0",
+        "duration": "17.0",
         "name": "rendering.mobile/motionmark_html_css_bouncing_gradient_circles_250"
     },
     {
-        "duration": "19.0",
+        "duration": "17.0",
         "name": "rendering.mobile/motionmark_html_css_bouncing_svg_images_50"
     },
     {
-        "duration": "19.0",
+        "duration": "17.0",
         "name": "rendering.mobile/motionmark_html_css_bouncing_tagged_images_225"
     },
     {
-        "duration": "19.0",
+        "duration": "17.0",
         "name": "rendering.mobile/motionmark_html_dom_particles_svg_masks_25"
     },
     {
-        "duration": "18.0",
+        "duration": "17.0",
         "name": "rendering.mobile/motionmark_html_focus_20_15"
     },
     {
-        "duration": "19.0",
+        "duration": "17.0",
         "name": "rendering.mobile/motionmark_html_leaves_20_50"
     },
     {
-        "duration": "19.0",
+        "duration": "17.0",
         "name": "rendering.mobile/motionmark_svg_bouncing_circles_250"
     },
     {
-        "duration": "19.0",
+        "duration": "17.0",
         "name": "rendering.mobile/motionmark_svg_bouncing_clipped_rects_100"
     },
     {
-        "duration": "19.0",
+        "duration": "17.0",
         "name": "rendering.mobile/motionmark_svg_bouncing_gradient_circles_200"
     },
     {
-        "duration": "19.0",
+        "duration": "17.0",
         "name": "rendering.mobile/motionmark_svg_bouncing_png_images_200"
     },
     {
-        "duration": "23.0",
+        "duration": "20.0",
         "name": "rendering.mobile/motionmark_svg_bouncing_svg_images_50"
     },
     {
@@ -2768,7 +2772,7 @@
         "name": "rendering.mobile/new_tilings"
     },
     {
-        "duration": "15.0",
+        "duration": "16.0",
         "name": "rendering.mobile/no_op_raf"
     },
     {
@@ -2780,27 +2784,27 @@
         "name": "rendering.mobile/no_op_settimeout"
     },
     {
-        "duration": "15.0",
+        "duration": "16.0",
         "name": "rendering.mobile/no_op_touch_handler"
     },
     {
-        "duration": "17.0",
+        "duration": "16.0",
         "name": "rendering.mobile/nvidia_vertex_buffer_object"
     },
     {
-        "duration": "23.0",
+        "duration": "22.0",
         "name": "rendering.mobile/nyc_gov_scroll_2018"
     },
     {
-        "duration": "25.0",
+        "duration": "18.0",
         "name": "rendering.mobile/nytimes_mobile_2018"
     },
     {
-        "duration": "23.0",
+        "duration": "22.0",
         "name": "rendering.mobile/nytimes_scroll_2018"
     },
     {
-        "duration": "23.0",
+        "duration": "22.0",
         "name": "rendering.mobile/overlay_background_color_css_transitions_page"
     },
     {
@@ -2808,11 +2812,11 @@
         "name": "rendering.mobile/parallax_effect"
     },
     {
-        "duration": "16.0",
+        "duration": "17.0",
         "name": "rendering.mobile/particles"
     },
     {
-        "duration": "16.0",
+        "duration": "14.0",
         "name": "rendering.mobile/pbs_pathological_2018"
     },
     {
@@ -2820,7 +2824,7 @@
         "name": "rendering.mobile/physical_simulation"
     },
     {
-        "duration": "22.0",
+        "duration": "16.0",
         "name": "rendering.mobile/pinterest_2018"
     },
     {
@@ -2832,7 +2836,7 @@
         "name": "rendering.mobile/put_get_image_data"
     },
     {
-        "duration": "16.0",
+        "duration": "15.0",
         "name": "rendering.mobile/raf"
     },
     {
@@ -2844,11 +2848,11 @@
         "name": "rendering.mobile/raf_canvas"
     },
     {
-        "duration": "16.0",
+        "duration": "15.0",
         "name": "rendering.mobile/raf_touch_animation"
     },
     {
-        "duration": "18.0",
+        "duration": "17.0",
         "name": "rendering.mobile/recode_pathological_2018"
     },
     {
@@ -2880,31 +2884,31 @@
         "name": "rendering.mobile/sfgate_mobile_2018"
     },
     {
-        "duration": "21.0",
+        "duration": "22.0",
         "name": "rendering.mobile/silk_finance"
     },
     {
-        "duration": "15.0",
+        "duration": "16.0",
         "name": "rendering.mobile/simple_text_page"
     },
     {
-        "duration": "11.0",
+        "duration": "12.0",
         "name": "rendering.mobile/simple_touch_drag"
     },
     {
-        "duration": "15.0",
+        "duration": "14.0",
         "name": "rendering.mobile/slashdot_mobile_2018"
     },
     {
-        "duration": "12.0",
+        "duration": "13.0",
         "name": "rendering.mobile/slide_drawer"
     },
     {
-        "duration": "19.0",
+        "duration": "20.0",
         "name": "rendering.mobile/small_texture_uploads"
     },
     {
-        "duration": "13.0",
+        "duration": "12.0",
         "name": "rendering.mobile/spielzeugz"
     },
     {
@@ -2912,19 +2916,19 @@
         "name": "rendering.mobile/sticky_using_webkit"
     },
     {
-        "duration": "20.0",
+        "duration": "19.0",
         "name": "rendering.mobile/stress_hidey_bars"
     },
     {
-        "duration": "12.0",
+        "duration": "13.0",
         "name": "rendering.mobile/stroke_shapes"
     },
     {
-        "duration": "24.0",
+        "duration": "23.0",
         "name": "rendering.mobile/svg_icon_raster"
     },
     {
-        "duration": "9.0",
+        "duration": "10.0",
         "name": "rendering.mobile/swipe_action"
     },
     {
@@ -2932,15 +2936,15 @@
         "name": "rendering.mobile/swipe_to_dismiss"
     },
     {
-        "duration": "14.0",
+        "duration": "15.0",
         "name": "rendering.mobile/sync_scroll_offset"
     },
     {
-        "duration": "21.0",
+        "duration": "19.0",
         "name": "rendering.mobile/techcrunch_2018"
     },
     {
-        "duration": "19.0",
+        "duration": "18.0",
         "name": "rendering.mobile/techcrunch_mobile_2018"
     },
     {
@@ -2956,7 +2960,7 @@
         "name": "rendering.mobile/text_20000_pixels_per_second"
     },
     {
-        "duration": "9.0",
+        "duration": "10.0",
         "name": "rendering.mobile/text_40000_pixels_per_second"
     },
     {
@@ -2968,7 +2972,7 @@
         "name": "rendering.mobile/text_75000_pixels_per_second"
     },
     {
-        "duration": "8.0",
+        "duration": "9.0",
         "name": "rendering.mobile/text_90000_pixels_per_second"
     },
     {
@@ -2992,7 +2996,7 @@
         "name": "rendering.mobile/text_constant_full_page_raster_60000_pixels_per_second"
     },
     {
-        "duration": "8.0",
+        "duration": "9.0",
         "name": "rendering.mobile/text_constant_full_page_raster_75000_pixels_per_second"
     },
     {
@@ -3016,11 +3020,11 @@
         "name": "rendering.mobile/text_hover_40000_pixels_per_second"
     },
     {
-        "duration": "8.0",
+        "duration": "9.0",
         "name": "rendering.mobile/text_hover_60000_pixels_per_second"
     },
     {
-        "duration": "8.0",
+        "duration": "9.0",
         "name": "rendering.mobile/text_hover_75000_pixels_per_second"
     },
     {
@@ -3028,7 +3032,7 @@
         "name": "rendering.mobile/text_hover_90000_pixels_per_second"
     },
     {
-        "duration": "20.0",
+        "duration": "19.0",
         "name": "rendering.mobile/theverge_article_mobile_2018"
     },
     {
@@ -3040,7 +3044,7 @@
         "name": "rendering.mobile/toggle_drawer"
     },
     {
-        "duration": "15.0",
+        "duration": "16.0",
         "name": "rendering.mobile/touch_handler_scrolling"
     },
     {
@@ -3048,11 +3052,11 @@
         "name": "rendering.mobile/transform_transitions"
     },
     {
-        "duration": "18.0",
+        "duration": "19.0",
         "name": "rendering.mobile/transform_transitions_js_block"
     },
     {
-        "duration": "16.0",
+        "duration": "13.0",
         "name": "rendering.mobile/twitch_2018"
     },
     {
@@ -3060,7 +3064,7 @@
         "name": "rendering.mobile/twitch_mobile_pinch_2018"
     },
     {
-        "duration": "20.0",
+        "duration": "18.0",
         "name": "rendering.mobile/twitter_2018"
     },
     {
@@ -3068,7 +3072,7 @@
         "name": "rendering.mobile/twitter_mobile_2018"
     },
     {
-        "duration": "15.0",
+        "duration": "16.0",
         "name": "rendering.mobile/update_history_state"
     },
     {
@@ -3084,11 +3088,11 @@
         "name": "rendering.mobile/web_animation_value_type_color"
     },
     {
-        "duration": "18.0",
+        "duration": "19.0",
         "name": "rendering.mobile/web_animation_value_type_length_3d"
     },
     {
-        "duration": "19.0",
+        "duration": "20.0",
         "name": "rendering.mobile/web_animation_value_type_length_complex"
     },
     {
@@ -3100,15 +3104,15 @@
         "name": "rendering.mobile/web_animation_value_type_path"
     },
     {
-        "duration": "28.0",
+        "duration": "20.0",
         "name": "rendering.mobile/web_animation_value_type_shadow"
     },
     {
-        "duration": "19.0",
+        "duration": "18.0",
         "name": "rendering.mobile/web_animation_value_type_transform_complex"
     },
     {
-        "duration": "19.0",
+        "duration": "18.0",
         "name": "rendering.mobile/web_animation_value_type_transform_simple"
     },
     {
@@ -3116,11 +3120,11 @@
         "name": "rendering.mobile/web_animations_many_keyframes"
     },
     {
-        "duration": "19.0",
+        "duration": "18.0",
         "name": "rendering.mobile/web_animations_set_current_time"
     },
     {
-        "duration": "19.0",
+        "duration": "18.0",
         "name": "rendering.mobile/web_animations_simultaneous"
     },
     {
@@ -3132,39 +3136,47 @@
         "name": "rendering.mobile/web_animations_staggered_infinite_iterations"
     },
     {
-        "duration": "21.0",
+        "duration": "20.0",
         "name": "rendering.mobile/web_animations_staggered_triggering_page"
     },
     {
-        "duration": "19.0",
+        "duration": "12.0",
+        "name": "rendering.mobile/webp_decoding_rgb_and_gpu_rasterization"
+    },
+    {
+        "duration": "12.0",
+        "name": "rendering.mobile/webp_decoding_yuv_and_gpu_rasterization"
+    },
+    {
+        "duration": "18.0",
         "name": "rendering.mobile/wikipedia_2018"
     },
     {
-        "duration": "18.0",
+        "duration": "17.0",
         "name": "rendering.mobile/wikipedia_delayed_scroll_start_2018"
     },
     {
-        "duration": "18.0",
+        "duration": "17.0",
         "name": "rendering.mobile/wikipedia_mobile_2018"
     },
     {
-        "duration": "20.0",
+        "duration": "18.0",
         "name": "rendering.mobile/wordpress_2018"
     },
     {
-        "duration": "18.0",
+        "duration": "17.0",
         "name": "rendering.mobile/wordpress_mobile_2018"
     },
     {
-        "duration": "18.0",
+        "duration": "17.0",
         "name": "rendering.mobile/worldjournal_mobile_2018"
     },
     {
-        "duration": "20.0",
+        "duration": "19.0",
         "name": "rendering.mobile/wow_wiki_pathological_2018"
     },
     {
-        "duration": "32.0",
+        "duration": "30.0",
         "name": "rendering.mobile/wowwiki_mobile_2018"
     },
     {
@@ -3172,11 +3184,11 @@
         "name": "rendering.mobile/wsj_mobile_2018"
     },
     {
-        "duration": "12.0",
+        "duration": "11.0",
         "name": "rendering.mobile/yahoo_answers_2018"
     },
     {
-        "duration": "15.0",
+        "duration": "13.0",
         "name": "rendering.mobile/yahoo_news_2018"
     },
     {
@@ -3184,15 +3196,15 @@
         "name": "rendering.mobile/yahoo_news_mobile_2018"
     },
     {
-        "duration": "20.0",
+        "duration": "15.0",
         "name": "rendering.mobile/yahoo_sports_2018"
     },
     {
-        "duration": "10.0",
+        "duration": "9.0",
         "name": "rendering.mobile/yahoo_sports_pathological_2018"
     },
     {
-        "duration": "16.0",
+        "duration": "14.0",
         "name": "rendering.mobile/youtube_2018"
     },
     {
@@ -3200,14 +3212,6 @@
         "name": "rendering.mobile/youtube_mobile_2018"
     },
     {
-        "duration": "22.0",
-        "name": "rendering.mobile/yuv_decoding"
-    },
-    {
-        "duration": "22.0",
-        "name": "rendering.mobile/yuv_decoding_gpu_rasterization_and_decoding"
-    },
-    {
         "duration": "17.0",
         "name": "rendering.mobile/zdnet_pathological_2018"
     },
@@ -3216,102 +3220,6 @@
         "name": "rendering.mobile/zoom_in_animation"
     },
     {
-        "duration": "14.0",
-        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/amazon_pinch_2018"
-    },
-    {
-        "duration": "13.0",
-        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/blogspot_pinch_2018"
-    },
-    {
-        "duration": "14.0",
-        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/booking_pinch_2018"
-    },
-    {
-        "duration": "16.0",
-        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/espn_pinch_2018"
-    },
-    {
-        "duration": "14.0",
-        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/facebook_pinch_2018"
-    },
-    {
-        "duration": "29.0",
-        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/gmail_pinch_2018"
-    },
-    {
-        "duration": "13.0",
-        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/google_calendar_pinch_2018"
-    },
-    {
-        "duration": "12.0",
-        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/google_image_pinch_2018"
-    },
-    {
-        "duration": "14.0",
-        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/twitter_pinch_2018"
-    },
-    {
-        "duration": "19.0",
-        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/yahoo_news_pinch_2018"
-    },
-    {
-        "duration": "20.0",
-        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/yahoo_sports_pinch_2018"
-    },
-    {
-        "duration": "14.0",
-        "name": "smoothness.gpu_rasterization.tough_pinch_zoom_cases/youtube_pinch_2018"
-    },
-    {
-        "duration": "15.0",
-        "name": "smoothness.tough_pinch_zoom_cases/amazon_pinch_2018"
-    },
-    {
-        "duration": "20.0",
-        "name": "smoothness.tough_pinch_zoom_cases/blogspot_pinch_2018"
-    },
-    {
-        "duration": "15.0",
-        "name": "smoothness.tough_pinch_zoom_cases/booking_pinch_2018"
-    },
-    {
-        "duration": "16.0",
-        "name": "smoothness.tough_pinch_zoom_cases/espn_pinch_2018"
-    },
-    {
-        "duration": "14.0",
-        "name": "smoothness.tough_pinch_zoom_cases/facebook_pinch_2018"
-    },
-    {
-        "duration": "26.0",
-        "name": "smoothness.tough_pinch_zoom_cases/gmail_pinch_2018"
-    },
-    {
-        "duration": "13.0",
-        "name": "smoothness.tough_pinch_zoom_cases/google_calendar_pinch_2018"
-    },
-    {
-        "duration": "12.0",
-        "name": "smoothness.tough_pinch_zoom_cases/google_image_pinch_2018"
-    },
-    {
-        "duration": "14.0",
-        "name": "smoothness.tough_pinch_zoom_cases/twitter_pinch_2018"
-    },
-    {
-        "duration": "21.0",
-        "name": "smoothness.tough_pinch_zoom_cases/yahoo_news_pinch_2018"
-    },
-    {
-        "duration": "23.0",
-        "name": "smoothness.tough_pinch_zoom_cases/yahoo_sports_pinch_2018"
-    },
-    {
-        "duration": "14.0",
-        "name": "smoothness.tough_pinch_zoom_cases/youtube_pinch_2018"
-    },
-    {
         "duration": "32.0",
         "name": "speedometer-future/http://browserbench.org/Speedometer/"
     },
@@ -3320,19 +3228,19 @@
         "name": "speedometer/http://browserbench.org/Speedometer/"
     },
     {
-        "duration": "53.0",
+        "duration": "52.0",
         "name": "speedometer2-future/Speedometer2"
     },
     {
-        "duration": "53.0",
+        "duration": "51.0",
         "name": "speedometer2/Speedometer2"
     },
     {
-        "duration": "18.0",
+        "duration": "17.0",
         "name": "system_health.common_mobile/background:media:imgur"
     },
     {
-        "duration": "18.0",
+        "duration": "19.0",
         "name": "system_health.common_mobile/background:search:google"
     },
     {
@@ -3340,39 +3248,35 @@
         "name": "system_health.common_mobile/background:social:facebook"
     },
     {
-        "duration": "10.0",
+        "duration": "9.0",
         "name": "system_health.common_mobile/browse:chrome:newtab"
     },
     {
-        "duration": "9.0",
+        "duration": "8.0",
         "name": "system_health.common_mobile/browse:chrome:omnibox"
     },
     {
-        "duration": "72.0",
+        "duration": "71.0",
         "name": "system_health.common_mobile/browse:media:facebook_photos"
     },
     {
-        "duration": "42.0",
+        "duration": "41.0",
         "name": "system_health.common_mobile/browse:media:flickr_infinite_scroll"
     },
     {
-        "duration": "40.0",
+        "duration": "39.0",
         "name": "system_health.common_mobile/browse:media:googleplaystore:2019"
     },
     {
-        "duration": "67.0",
+        "duration": "66.0",
         "name": "system_health.common_mobile/browse:media:imgur"
     },
     {
-        "duration": "86.0",
+        "duration": "83.0",
         "name": "system_health.common_mobile/browse:media:youtube"
     },
     {
-        "duration": "57.0",
-        "name": "system_health.common_mobile/browse:news:cnn"
-    },
-    {
-        "duration": "60.0",
+        "duration": "51.0",
         "name": "system_health.common_mobile/browse:news:cnn:2018"
     },
     {
@@ -3380,7 +3284,7 @@
         "name": "system_health.common_mobile/browse:news:cricbuzz"
     },
     {
-        "duration": "52.0",
+        "duration": "46.0",
         "name": "system_health.common_mobile/browse:news:qq"
     },
     {
@@ -3388,19 +3292,23 @@
         "name": "system_health.common_mobile/browse:news:reddit"
     },
     {
-        "duration": "102.0",
+        "duration": "86.0",
         "name": "system_health.common_mobile/browse:news:toi"
     },
     {
-        "duration": "45.0",
+        "duration": "44.0",
         "name": "system_health.common_mobile/browse:news:washingtonpost"
     },
     {
-        "duration": "22.0",
+        "duration": "21.0",
         "name": "system_health.common_mobile/browse:search:amp:2018"
     },
     {
-        "duration": "52.0",
+        "duration": "22.0",
+        "name": "system_health.common_mobile/browse:search:amp:sxg:2019"
+    },
+    {
+        "duration": "53.0",
         "name": "system_health.common_mobile/browse:shopping:amazon"
     },
     {
@@ -3408,47 +3316,43 @@
         "name": "system_health.common_mobile/browse:shopping:lazada"
     },
     {
-        "duration": "55.0",
+        "duration": "54.0",
         "name": "system_health.common_mobile/browse:social:facebook"
     },
     {
-        "duration": "88.0",
+        "duration": "84.0",
         "name": "system_health.common_mobile/browse:social:facebook_infinite_scroll"
     },
     {
-        "duration": "78.0",
+        "duration": "72.0",
         "name": "system_health.common_mobile/browse:social:facebook_infinite_scroll:2018"
     },
     {
-        "duration": "71.0",
+        "duration": "70.0",
         "name": "system_health.common_mobile/browse:social:instagram"
     },
     {
-        "duration": "75.0",
+        "duration": "69.0",
         "name": "system_health.common_mobile/browse:social:pinterest_infinite_scroll"
     },
     {
-        "duration": "77.0",
-        "name": "system_health.common_mobile/browse:social:tumblr_infinite_scroll"
-    },
-    {
-        "duration": "72.0",
+        "duration": "69.0",
         "name": "system_health.common_mobile/browse:social:tumblr_infinite_scroll:2018"
     },
     {
-        "duration": "45.0",
+        "duration": "44.0",
         "name": "system_health.common_mobile/browse:social:twitter"
     },
     {
-        "duration": "55.0",
+        "duration": "52.0",
         "name": "system_health.common_mobile/browse:tech:discourse_infinite_scroll"
     },
     {
-        "duration": "73.0",
+        "duration": "70.0",
         "name": "system_health.common_mobile/browse:tech:discourse_infinite_scroll:2018"
     },
     {
-        "duration": "39.0",
+        "duration": "38.0",
         "name": "system_health.common_mobile/browse:tools:maps"
     },
     {
@@ -3464,11 +3368,7 @@
         "name": "system_health.common_mobile/load:games:lazors"
     },
     {
-        "duration": "22.0",
-        "name": "system_health.common_mobile/load:games:spychase"
-    },
-    {
-        "duration": "24.0",
+        "duration": "23.0",
         "name": "system_health.common_mobile/load:games:spychase:2018"
     },
     {
@@ -3480,43 +3380,27 @@
         "name": "system_health.common_mobile/load:media:facebook_photos"
     },
     {
-        "duration": "19.0",
+        "duration": "20.0",
         "name": "system_health.common_mobile/load:media:flickr:2018"
     },
     {
-        "duration": "16.0",
-        "name": "system_health.common_mobile/load:media:google_images"
-    },
-    {
         "duration": "17.0",
         "name": "system_health.common_mobile/load:media:google_images:2018"
     },
     {
-        "duration": "16.0",
-        "name": "system_health.common_mobile/load:media:imgur"
-    },
-    {
-        "duration": "21.0",
+        "duration": "24.0",
         "name": "system_health.common_mobile/load:media:imgur:2018"
     },
     {
-        "duration": "16.0",
-        "name": "system_health.common_mobile/load:media:youtube"
-    },
-    {
         "duration": "18.0",
         "name": "system_health.common_mobile/load:media:youtube:2018"
     },
     {
-        "duration": "22.0",
-        "name": "system_health.common_mobile/load:news:cnn"
-    },
-    {
-        "duration": "22.0",
+        "duration": "23.0",
         "name": "system_health.common_mobile/load:news:cnn:2018"
     },
     {
-        "duration": "19.0",
+        "duration": "18.0",
         "name": "system_health.common_mobile/load:news:irctc"
     },
     {
@@ -3524,7 +3408,7 @@
         "name": "system_health.common_mobile/load:news:nytimes"
     },
     {
-        "duration": "19.0",
+        "duration": "17.0",
         "name": "system_health.common_mobile/load:news:qq"
     },
     {
@@ -3537,54 +3421,30 @@
     },
     {
         "duration": "17.0",
-        "name": "system_health.common_mobile/load:news:wikipedia"
-    },
-    {
-        "duration": "17.0",
         "name": "system_health.common_mobile/load:news:wikipedia:2018"
     },
     {
-        "duration": "19.0",
-        "name": "system_health.common_mobile/load:search:baidu"
-    },
-    {
-        "duration": "20.0",
+        "duration": "18.0",
         "name": "system_health.common_mobile/load:search:baidu:2018"
     },
     {
-        "duration": "16.0",
-        "name": "system_health.common_mobile/load:search:ebay"
-    },
-    {
-        "duration": "18.0",
+        "duration": "17.0",
         "name": "system_health.common_mobile/load:search:ebay:2018"
     },
     {
-        "duration": "16.0",
-        "name": "system_health.common_mobile/load:search:google"
-    },
-    {
         "duration": "17.0",
         "name": "system_health.common_mobile/load:search:google:2018"
     },
     {
-        "duration": "17.0",
+        "duration": "24.0",
         "name": "system_health.common_mobile/load:search:taobao"
     },
     {
-        "duration": "15.0",
-        "name": "system_health.common_mobile/load:search:yahoo"
-    },
-    {
         "duration": "16.0",
         "name": "system_health.common_mobile/load:search:yahoo:2018"
     },
     {
-        "duration": "16.0",
-        "name": "system_health.common_mobile/load:search:yandex"
-    },
-    {
-        "duration": "18.0",
+        "duration": "17.0",
         "name": "system_health.common_mobile/load:search:yandex:2018"
     },
     {
@@ -3592,7 +3452,7 @@
         "name": "system_health.common_mobile/load:social:twitter"
     },
     {
-        "duration": "17.0",
+        "duration": "16.0",
         "name": "system_health.common_mobile/load:tools:docs"
     },
     {
@@ -3604,11 +3464,7 @@
         "name": "system_health.common_mobile/load:tools:dropbox"
     },
     {
-        "duration": "16.0",
-        "name": "system_health.common_mobile/load:tools:stackoverflow"
-    },
-    {
-        "duration": "18.0",
+        "duration": "17.0",
         "name": "system_health.common_mobile/load:tools:stackoverflow:2018"
     },
     {
@@ -3616,11 +3472,11 @@
         "name": "system_health.common_mobile/load:tools:weather"
     },
     {
-        "duration": "22.0",
+        "duration": "21.0",
         "name": "system_health.memory_mobile/background:media:imgur"
     },
     {
-        "duration": "23.0",
+        "duration": "22.0",
         "name": "system_health.memory_mobile/background:search:google"
     },
     {
@@ -3636,7 +3492,7 @@
         "name": "system_health.memory_mobile/browse:chrome:omnibox"
     },
     {
-        "duration": "79.0",
+        "duration": "72.0",
         "name": "system_health.memory_mobile/browse:media:facebook_photos"
     },
     {
@@ -3644,11 +3500,11 @@
         "name": "system_health.memory_mobile/browse:media:flickr_infinite_scroll"
     },
     {
-        "duration": "43.0",
+        "duration": "40.0",
         "name": "system_health.memory_mobile/browse:media:googleplaystore:2019"
     },
     {
-        "duration": "67.0",
+        "duration": "68.0",
         "name": "system_health.memory_mobile/browse:media:imgur"
     },
     {
@@ -3656,19 +3512,15 @@
         "name": "system_health.memory_mobile/browse:media:youtube"
     },
     {
-        "duration": "59.0",
-        "name": "system_health.memory_mobile/browse:news:cnn"
-    },
-    {
-        "duration": "60.0",
+        "duration": "48.0",
         "name": "system_health.memory_mobile/browse:news:cnn:2018"
     },
     {
-        "duration": "58.0",
+        "duration": "57.0",
         "name": "system_health.memory_mobile/browse:news:cricbuzz"
     },
     {
-        "duration": "53.0",
+        "duration": "47.0",
         "name": "system_health.memory_mobile/browse:news:qq"
     },
     {
@@ -3676,7 +3528,7 @@
         "name": "system_health.memory_mobile/browse:news:reddit"
     },
     {
-        "duration": "80.0",
+        "duration": "71.0",
         "name": "system_health.memory_mobile/browse:news:toi"
     },
     {
@@ -3688,15 +3540,19 @@
         "name": "system_health.memory_mobile/browse:search:amp:2018"
     },
     {
-        "duration": "53.0",
+        "duration": "25.0",
+        "name": "system_health.memory_mobile/browse:search:amp:sxg:2019"
+    },
+    {
+        "duration": "52.0",
         "name": "system_health.memory_mobile/browse:shopping:amazon"
     },
     {
-        "duration": "30.0",
+        "duration": "29.0",
         "name": "system_health.memory_mobile/browse:shopping:lazada"
     },
     {
-        "duration": "57.0",
+        "duration": "55.0",
         "name": "system_health.memory_mobile/browse:social:facebook"
     },
     {
@@ -3708,15 +3564,11 @@
         "name": "system_health.memory_mobile/browse:social:instagram"
     },
     {
-        "duration": "71.0",
+        "duration": "67.0",
         "name": "system_health.memory_mobile/browse:social:pinterest_infinite_scroll"
     },
     {
-        "duration": "73.0",
-        "name": "system_health.memory_mobile/browse:social:tumblr_infinite_scroll"
-    },
-    {
-        "duration": "67.0",
+        "duration": "64.0",
         "name": "system_health.memory_mobile/browse:social:tumblr_infinite_scroll:2018"
     },
     {
@@ -3724,11 +3576,11 @@
         "name": "system_health.memory_mobile/browse:social:twitter"
     },
     {
-        "duration": "53.0",
+        "duration": "52.0",
         "name": "system_health.memory_mobile/browse:tech:discourse_infinite_scroll"
     },
     {
-        "duration": "42.0",
+        "duration": "41.0",
         "name": "system_health.memory_mobile/browse:tools:maps"
     },
     {
@@ -3745,10 +3597,6 @@
     },
     {
         "duration": "25.0",
-        "name": "system_health.memory_mobile/load:games:spychase"
-    },
-    {
-        "duration": "26.0",
         "name": "system_health.memory_mobile/load:games:spychase:2018"
     },
     {
@@ -3760,43 +3608,27 @@
         "name": "system_health.memory_mobile/load:media:facebook_photos"
     },
     {
-        "duration": "26.0",
+        "duration": "23.0",
         "name": "system_health.memory_mobile/load:media:flickr:2018"
     },
     {
-        "duration": "20.0",
-        "name": "system_health.memory_mobile/load:media:google_images"
-    },
-    {
         "duration": "21.0",
         "name": "system_health.memory_mobile/load:media:google_images:2018"
     },
     {
-        "duration": "20.0",
-        "name": "system_health.memory_mobile/load:media:imgur"
-    },
-    {
-        "duration": "24.0",
+        "duration": "22.0",
         "name": "system_health.memory_mobile/load:media:imgur:2018"
     },
     {
-        "duration": "20.0",
-        "name": "system_health.memory_mobile/load:media:youtube"
-    },
-    {
-        "duration": "23.0",
+        "duration": "21.0",
         "name": "system_health.memory_mobile/load:media:youtube:2018"
     },
     {
-        "duration": "25.0",
-        "name": "system_health.memory_mobile/load:news:cnn"
-    },
-    {
-        "duration": "27.0",
+        "duration": "24.0",
         "name": "system_health.memory_mobile/load:news:cnn:2018"
     },
     {
-        "duration": "22.0",
+        "duration": "21.0",
         "name": "system_health.memory_mobile/load:news:irctc"
     },
     {
@@ -3804,7 +3636,7 @@
         "name": "system_health.memory_mobile/load:news:nytimes"
     },
     {
-        "duration": "23.0",
+        "duration": "21.0",
         "name": "system_health.memory_mobile/load:news:qq"
     },
     {
@@ -3816,55 +3648,31 @@
         "name": "system_health.memory_mobile/load:news:washingtonpost"
     },
     {
-        "duration": "22.0",
-        "name": "system_health.memory_mobile/load:news:wikipedia"
-    },
-    {
-        "duration": "22.0",
+        "duration": "21.0",
         "name": "system_health.memory_mobile/load:news:wikipedia:2018"
     },
     {
-        "duration": "25.0",
-        "name": "system_health.memory_mobile/load:search:baidu"
-    },
-    {
-        "duration": "24.0",
+        "duration": "23.0",
         "name": "system_health.memory_mobile/load:search:baidu:2018"
     },
     {
-        "duration": "20.0",
-        "name": "system_health.memory_mobile/load:search:ebay"
-    },
-    {
-        "duration": "22.0",
+        "duration": "21.0",
         "name": "system_health.memory_mobile/load:search:ebay:2018"
     },
     {
-        "duration": "20.0",
-        "name": "system_health.memory_mobile/load:search:google"
-    },
-    {
         "duration": "21.0",
         "name": "system_health.memory_mobile/load:search:google:2018"
     },
     {
-        "duration": "21.0",
+        "duration": "24.0",
         "name": "system_health.memory_mobile/load:search:taobao"
     },
     {
         "duration": "20.0",
-        "name": "system_health.memory_mobile/load:search:yahoo"
-    },
-    {
-        "duration": "21.0",
         "name": "system_health.memory_mobile/load:search:yahoo:2018"
     },
     {
-        "duration": "20.0",
-        "name": "system_health.memory_mobile/load:search:yandex"
-    },
-    {
-        "duration": "22.0",
+        "duration": "21.0",
         "name": "system_health.memory_mobile/load:search:yandex:2018"
     },
     {
@@ -3880,11 +3688,7 @@
         "name": "system_health.memory_mobile/load:tools:dropbox"
     },
     {
-        "duration": "20.0",
-        "name": "system_health.memory_mobile/load:tools:stackoverflow"
-    },
-    {
-        "duration": "22.0",
+        "duration": "21.0",
         "name": "system_health.memory_mobile/load:tools:stackoverflow:2018"
     },
     {
@@ -3896,7 +3700,7 @@
         "name": "system_health.webview_startup/load:chrome:blank"
     },
     {
-        "duration": "6.0",
+        "duration": "7.0",
         "name": "tracing.tracing_with_background_memory_infra/Facebook"
     },
     {
@@ -3920,7 +3724,7 @@
         "name": "tracing.tracing_with_background_memory_infra/http://www.yahoo.com/"
     },
     {
-        "duration": "7.0",
+        "duration": "8.0",
         "name": "tracing.tracing_with_background_memory_infra/http://www.youtube.com"
     },
     {
@@ -3928,7 +3732,7 @@
         "name": "tracing.tracing_with_background_memory_infra/https://www.google.com/#hl=en&q=barack+obama"
     },
     {
-        "duration": "7.0",
+        "duration": "8.0",
         "name": "tracing.tracing_with_background_memory_infra/https://www.google.com/calendar/"
     },
     {
@@ -3944,11 +3748,11 @@
         "name": "v8.browsing_mobile-future/browse:media:facebook_photos"
     },
     {
-        "duration": "50.0",
+        "duration": "46.0",
         "name": "v8.browsing_mobile-future/browse:media:flickr_infinite_scroll"
     },
     {
-        "duration": "44.0",
+        "duration": "43.0",
         "name": "v8.browsing_mobile-future/browse:media:googleplaystore:2019"
     },
     {
@@ -3956,43 +3760,39 @@
         "name": "v8.browsing_mobile-future/browse:media:imgur"
     },
     {
-        "duration": "94.0",
+        "duration": "91.0",
         "name": "v8.browsing_mobile-future/browse:media:youtube"
     },
     {
-        "duration": "101.0",
-        "name": "v8.browsing_mobile-future/browse:news:cnn"
-    },
-    {
-        "duration": "66.0",
+        "duration": "64.0",
         "name": "v8.browsing_mobile-future/browse:news:cnn:2018"
     },
     {
-        "duration": "59.0",
+        "duration": "61.0",
         "name": "v8.browsing_mobile-future/browse:news:cricbuzz"
     },
     {
-        "duration": "56.0",
+        "duration": "58.0",
         "name": "v8.browsing_mobile-future/browse:news:qq"
     },
     {
-        "duration": "48.0",
+        "duration": "49.0",
         "name": "v8.browsing_mobile-future/browse:news:reddit"
     },
     {
-        "duration": "99.0",
-        "name": "v8.browsing_mobile-future/browse:news:toi"
-    },
-    {
         "duration": "49.0",
         "name": "v8.browsing_mobile-future/browse:news:washingtonpost"
     },
     {
-        "duration": "24.0",
+        "duration": "23.0",
         "name": "v8.browsing_mobile-future/browse:search:amp:2018"
     },
     {
-        "duration": "60.0",
+        "duration": "24.0",
+        "name": "v8.browsing_mobile-future/browse:search:amp:sxg:2019"
+    },
+    {
+        "duration": "59.0",
         "name": "v8.browsing_mobile-future/browse:shopping:amazon"
     },
     {
@@ -4000,27 +3800,27 @@
         "name": "v8.browsing_mobile-future/browse:shopping:lazada"
     },
     {
-        "duration": "61.0",
+        "duration": "60.0",
         "name": "v8.browsing_mobile-future/browse:social:facebook"
     },
     {
-        "duration": "87.0",
-        "name": "v8.browsing_mobile-future/browse:social:facebook_infinite_scroll:2018"
-    },
-    {
-        "duration": "79.0",
-        "name": "v8.browsing_mobile-future/browse:social:instagram"
+        "duration": "100.0",
+        "name": "v8.browsing_mobile-future/browse:social:facebook_infinite_scroll"
     },
     {
         "duration": "86.0",
+        "name": "v8.browsing_mobile-future/browse:social:facebook_infinite_scroll:2018"
+    },
+    {
+        "duration": "78.0",
+        "name": "v8.browsing_mobile-future/browse:social:instagram"
+    },
+    {
+        "duration": "80.0",
         "name": "v8.browsing_mobile-future/browse:social:pinterest_infinite_scroll"
     },
     {
-        "duration": "89.0",
-        "name": "v8.browsing_mobile-future/browse:social:tumblr_infinite_scroll"
-    },
-    {
-        "duration": "85.0",
+        "duration": "82.0",
         "name": "v8.browsing_mobile-future/browse:social:tumblr_infinite_scroll:2018"
     },
     {
@@ -4028,7 +3828,11 @@
         "name": "v8.browsing_mobile-future/browse:social:twitter"
     },
     {
-        "duration": "85.0",
+        "duration": "60.0",
+        "name": "v8.browsing_mobile-future/browse:tech:discourse_infinite_scroll"
+    },
+    {
+        "duration": "83.0",
         "name": "v8.browsing_mobile-future/browse:tech:discourse_infinite_scroll:2018"
     },
     {
@@ -4036,39 +3840,39 @@
         "name": "v8.browsing_mobile-future/browse:tools:maps"
     },
     {
-        "duration": "11.0",
+        "duration": "10.0",
         "name": "v8.browsing_mobile/browse:chrome:newtab"
     },
     {
-        "duration": "11.0",
+        "duration": "9.0",
         "name": "v8.browsing_mobile/browse:chrome:omnibox"
     },
     {
-        "duration": "82.0",
+        "duration": "77.0",
         "name": "v8.browsing_mobile/browse:media:facebook_photos"
     },
     {
-        "duration": "47.0",
+        "duration": "46.0",
         "name": "v8.browsing_mobile/browse:media:flickr_infinite_scroll"
     },
     {
-        "duration": "46.0",
+        "duration": "43.0",
         "name": "v8.browsing_mobile/browse:media:googleplaystore:2019"
     },
     {
-        "duration": "72.0",
+        "duration": "71.0",
         "name": "v8.browsing_mobile/browse:media:imgur"
     },
     {
-        "duration": "65.0",
+        "duration": "64.0",
         "name": "v8.browsing_mobile/browse:news:cnn:2018"
     },
     {
-        "duration": "59.0",
+        "duration": "61.0",
         "name": "v8.browsing_mobile/browse:news:cricbuzz"
     },
     {
-        "duration": "59.0",
+        "duration": "53.0",
         "name": "v8.browsing_mobile/browse:news:qq"
     },
     {
@@ -4076,11 +3880,7 @@
         "name": "v8.browsing_mobile/browse:news:reddit"
     },
     {
-        "duration": "100.0",
-        "name": "v8.browsing_mobile/browse:news:toi"
-    },
-    {
-        "duration": "50.0",
+        "duration": "49.0",
         "name": "v8.browsing_mobile/browse:news:washingtonpost"
     },
     {
@@ -4088,7 +3888,11 @@
         "name": "v8.browsing_mobile/browse:search:amp:2018"
     },
     {
-        "duration": "62.0",
+        "duration": "23.0",
+        "name": "v8.browsing_mobile/browse:search:amp:sxg:2019"
+    },
+    {
+        "duration": "59.0",
         "name": "v8.browsing_mobile/browse:shopping:amazon"
     },
     {
@@ -4096,31 +3900,27 @@
         "name": "v8.browsing_mobile/browse:shopping:lazada"
     },
     {
-        "duration": "62.0",
+        "duration": "59.0",
         "name": "v8.browsing_mobile/browse:social:facebook"
     },
     {
-        "duration": "91.0",
+        "duration": "100.0",
         "name": "v8.browsing_mobile/browse:social:facebook_infinite_scroll"
     },
     {
-        "duration": "88.0",
+        "duration": "85.0",
         "name": "v8.browsing_mobile/browse:social:facebook_infinite_scroll:2018"
     },
     {
-        "duration": "79.0",
+        "duration": "78.0",
         "name": "v8.browsing_mobile/browse:social:instagram"
     },
     {
-        "duration": "88.0",
+        "duration": "79.0",
         "name": "v8.browsing_mobile/browse:social:pinterest_infinite_scroll"
     },
     {
-        "duration": "89.0",
-        "name": "v8.browsing_mobile/browse:social:tumblr_infinite_scroll"
-    },
-    {
-        "duration": "87.0",
+        "duration": "82.0",
         "name": "v8.browsing_mobile/browse:social:tumblr_infinite_scroll:2018"
     },
     {
@@ -4128,11 +3928,11 @@
         "name": "v8.browsing_mobile/browse:social:twitter"
     },
     {
-        "duration": "62.0",
+        "duration": "60.0",
         "name": "v8.browsing_mobile/browse:tech:discourse_infinite_scroll"
     },
     {
-        "duration": "86.0",
+        "duration": "82.0",
         "name": "v8.browsing_mobile/browse:tech:discourse_infinite_scroll:2018"
     },
     {
@@ -4140,30 +3940,6 @@
         "name": "v8.browsing_mobile/browse:tools:maps"
     },
     {
-        "duration": "9.0",
-        "name": "wasm/AsmJsZenGarden"
-    },
-    {
-        "duration": "16.0",
-        "name": "wasm/WasmSpaceBuggy"
-    },
-    {
-        "duration": "9.0",
-        "name": "wasm/WasmStylizedRenderer"
-    },
-    {
-        "duration": "10.0",
-        "name": "wasm/WasmSunTemple"
-    },
-    {
-        "duration": "18.0",
-        "name": "wasm/WasmTanks"
-    },
-    {
-        "duration": "10.0",
-        "name": "wasm/WasmZenGarden"
-    },
-    {
         "duration": "15.0",
         "name": "webrtc/10s_datachannel_transfer"
     },
@@ -4192,7 +3968,7 @@
         "name": "webrtc/multiple_peerconnections"
     },
     {
-        "duration": "35.0",
+        "duration": "34.0",
         "name": "webrtc/pause_play_peerconnections"
     }
 ]
\ No newline at end of file
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config
index aa26e3501..5551a94 100644
--- a/tools/perf/expectations.config
+++ b/tools/perf/expectations.config
@@ -6,7 +6,7 @@
 # tags: Android_Webview Android_but_not_webview Mac Win Linux
 # tags: ChromeOS Android Desktop Nexus_5 Nexus_5X Nexus_6P
 # tags: Nexus_7 Mac_10.11 Mac_10.12 Nexus6_Webview Nexus5X_Webview
-# tags: Pixel_2 Win_7 Win_10 Android_Go_Webview
+# tags: Pixel_2 Win_7 Win_10 Android_Go_Webview Pixel2_Webview
 
 # Benchmark: blink_perf.bindings
 crbug.com/882881 [ Nexus_5 ] blink_perf.bindings/structured-clone-json-deserialize.html [ Skip ]
@@ -46,7 +46,10 @@
 crbug.com/963945 [ Nexus5X_Webview ] blink_perf.events/EventsDispatchingInDeeplyNestedV1ShadowTrees.html [ Skip ]
 crbug.com/966913 [ Nexus5X_Webview ] blink_perf.events/EventsDispatchingInV0ShadowTrees.html [ Skip ]
 crbug.com/966913 [ Nexus5X_Webview ] blink_perf.events/EventsDispatchingInV1ShadowTrees.html [ Skip ]
-
+crbug.com/966606 [ Pixel_2 ] blink_perf.events/EventsDispatchingInDeeplyNestedV0ShadowTrees.html [ Skip ]
+crbug.com/966606 [ Pixel_2 ] blink_perf.events/EventsDispatchingInDeeplyNestedV1ShadowTrees.html [ Skip ]
+crbug.com/966606 [ Pixel_2 ] blink_perf.events/EventsDispatchingInV0ShadowTrees.html [ Skip ]
+crbug.com/966606 [ Pixel_2 ] blink_perf.events/EventsDispatchingInV1ShadowTrees.html [ Skip ]
 
 # Benchmark: blink_perf.layout
 crbug.com/551950 [ Android_Svelte ] blink_perf.layout/* [ Skip ]
@@ -55,6 +58,7 @@
 crbug.com/963967 [ Android ] blink_perf.layout/line-layout-fit-content.html [ Skip ]
 crbug.com/966921 [ Nexus_5 ] blink_perf.layout/line-layout-fit-content-break-word.html [ Skip ]
 crbug.com/966921 [ Nexus_5 ] link_perf.layout/line-layout-fit-content.html [ Skip ]
+crbug.com/966609 [ Pixel_2 ] blink_perf.layout/line-layout-fit-content.html [ Skip ]
 
 # Benchmark: blink_perf.paint
 crbug.com/574483 [ Android_Svelte ] blink_perf.paint/* [ Skip ]
@@ -63,11 +67,15 @@
 crbug.com/859979 [ Android_Webview ] blink_perf.paint/paint-offset-changes.html [ Skip ]
 crbug.com/901493 [ Nexus6_Webview ] blink_perf.paint/* [ Skip ]
 crbug.com/963967 [ Android ] blink_perf.paint/select-all-words.html [ Skip ]
+crbug.com/966636 [ Pixel2_Webview ] blink_perf.paint/select-all-words.html [ Skip ]
 
 # Benchmark: blink_perf.parser
 crbug.com/966913 [ Nexus5X_Webview ] blink_perf.parser/query-selector-all-class-deep.html [ Skip ]
 crbug.com/966913 [ Nexus5X_Webview ] blink_perf.parser/query-selector-all-deep.html [ Skip ]
 crbug.com/966913 [ Nexus5X_Webview ] blink_perf.parser/query-selector-all-id-deep.html [ Skip ]
+crbug.com/966613 [ Pixel_2 ] blink_perf.parser/query-selector-all-class-deep.html [ Skip ]
+crbug.com/966613 [ Pixel_2 ] blink_perf.parser/query-selector-all-deep.html [ Skip ]
+crbug.com/966613 [ Pixel_2 ] blink_perf.parser/query-selector-all-id-deep.html [ Skip ]
 
 # Benchmark: blink_perf.shadow_dom
 crbug.com/702319 [ Nexus_5X ] blink_perf.shadow_dom/* [ Skip ]
@@ -169,16 +177,20 @@
 crbug.com/865400 [ Pixel_2 ] loading.mobile/TribunNews_3g [ Skip ]
 crbug.com/865400 [ Pixel_2 ] loading.mobile/Youtube_3g [ Skip ]
 crbug.com/914100 [ Nexus6_Webview ] loading.mobile/Wikipedia_3g [ Skip ]
-crbug.com/865400 [ Pixel_2 Android_Webview ] loading.mobile/BOLNoticias_3g [ Skip ]
-crbug.com/865400 [ Pixel_2 Android_Webview ] loading.mobile/FlipBoard_cold_3g [ Skip ]
-crbug.com/865400 [ Pixel_2 Android_Webview ] loading.mobile/FlipBoard_warm_3g [ Skip ]
-crbug.com/865400 [ Pixel_2 Android_Webview ] loading.mobile/FlipKart_warm_3g [ Skip ]
-crbug.com/865400 [ Pixel_2 Android_Webview ] loading.mobile/GoogleBrazil_3g [ Skip ]
-crbug.com/865400 [ Pixel_2 Android_Webview ] loading.mobile/GoogleIndonesia_3g [ Skip ]
-crbug.com/865400 [ Pixel_2 Android_Webview ] loading.mobile/Hongkiat_3g [ Skip ]
-crbug.com/865400 [ Pixel_2 Android_Webview ] loading.mobile/OLX_3g [ Skip ]
-crbug.com/865400 [ Pixel_2 Android_Webview ] loading.mobile/VoiceMemos_cold_3g [ Skip ]
+crbug.com/865400 [ Pixel2_Webview ] loading.mobile/BOLNoticias_3g [ Skip ]
+crbug.com/865400 [ Pixel2_Webview ] loading.mobile/FlipBoard_cold_3g [ Skip ]
+crbug.com/865400 [ Pixel2_Webview ] loading.mobile/FlipBoard_warm_3g [ Skip ]
+crbug.com/865400 [ Pixel2_Webview ] loading.mobile/FlipKart_warm_3g [ Skip ]
+crbug.com/865400 [ Pixel2_Webview ] loading.mobile/GoogleBrazil_3g [ Skip ]
+crbug.com/865400 [ Pixel2_Webview ] loading.mobile/GoogleIndonesia_3g [ Skip ]
+crbug.com/865400 [ Pixel2_Webview ] loading.mobile/Hongkiat_3g [ Skip ]
+crbug.com/865400 [ Pixel2_Webview ] loading.mobile/OLX_3g [ Skip ]
+crbug.com/865400 [ Pixel2_Webview ] loading.mobile/VoiceMemos_cold_3g [ Skip ]
 crbug.com/919191 [ Nexus5X_Webview ] loading.mobile/OLX_3g [ Skip ]
+crbug.com/966624 [ Pixel_2 ] loading.mobile/* [ Skip ] # mass disabling to set up the bot for pixel 2
+
+# Benchmark: memory.top_10_mobile
+crbug.com/966630 [ Pixel_2 ] memory.top_10_mobile/* [ Skip ] # mass disabling to set up the bot for pixel 2
 
 # Benchmark: oilpan_gc_times.key_silk_cases
 crbug.com/446332 [ All ] oilpan_gc_times.key_silk_cases/slide_drawer [ Skip ]
@@ -192,6 +204,9 @@
 crbug.com/755556 [ Mac ] rendering.desktop/mix_blend_mode_animation_difference [ Skip ]
 crbug.com/755556 [ Mac ] rendering.desktop/mix_blend_mode_animation_hue [ Skip ]
 
+# Benchmark: media.mobile
+crbug.com/966619 [ Pixel_2 ] media.mobile/* [ Skip ] # mass disabling to set up the bot for pixel 2
+
 # Benchmark: rendering.mobile
 crbug.com/785485 [ Android_Webview ] rendering.mobile/kevs_3d [ Skip ]
 crbug.com/785286 [ Android_Webview ] rendering.mobile/smash_cat [ Skip ]
@@ -231,6 +246,8 @@
 crbug.com/924400 [ Nexus6_Webview ] rendering.mobile/canvas_animation_no_clear [ Skip ]
 crbug.com/949366 [ Nexus5X_Webview ] rendering.mobile/google_news_mobile_2018 [ Skip ]
 crbug.com/954948 [ Android_Webview ] rendering.mobile/cnn_mobile_pinch_2018 [ Skip ]
+crbug.com/966637 [ Pixel2_Webview ] rendering.mobile/google_news_mobile_2018 [ Skip ]
+crbug.com/966631 [ Pixel_2 ] rendering.mobile/* [ Skip ] # mass disabling to set up the bot for pixel 2
 
 # Benchmark: rasterize_and_record_micro.top_25
 crbug.com/764543 [ All ] rasterize_and_record_micro.top_25/file://static_top_25/wikipedia.html [ Skip ]
@@ -326,6 +343,29 @@
 crbug.com/954949 [ Nexus5X_Webview ] system_health.memory_mobile/browse:news:washingtonpost [ Skip ]
 crbug.com/961417 [ Android_Go ] system_health.memory_mobile/browse:social:tumblr_infinite_scroll:2018 [ Skip ]
 
+crbug.com/964804 [ Nexus_5X ] system_health.memory_mobile/browse:media:flickr_infinite_scroll [ Skip ]
+crbug.com/964804 [ Nexus_5X ] system_health.memory_mobile/browse:search:amp:2018 [ Skip ]
+crbug.com/964804 [ Nexus_5X ] system_health.memory_mobile/load:games:lazors [ Skip ]
+crbug.com/964804 [ Nexus_5X ] system_health.memory_mobile/load:games:spychase:2018 [ Skip ]
+crbug.com/964804 [ Nexus_5X ] system_health.memory_mobile/load:media:flickr:2018 [ Skip ]
+crbug.com/964804 [ Nexus_5X ] system_health.memory_mobile/load:news:irctc [ Skip ]
+crbug.com/964804 [ Nexus_5X ] system_health.memory_mobile/load:search:baidu:2018 [ Skip ]
+crbug.com/964804 [ Nexus_5X ] system_health.memory_mobile/load:search:google:2018 [ Skip ]
+crbug.com/964804 [ Nexus_5X ] system_health.memory_mobile/load:tools:stackoverflow:2018 [ Skip ]
+crbug.com/964804 [ Nexus_5X ] system_health.memory_mobile/background:search:google [ Skip ]
+crbug.com/964804 [ Nexus_5X ] system_health.memory_mobile/browse:media:googleplaystore:2019 [ Skip ]
+crbug.com/964804 [ Nexus_5X ] system_health.memory_mobile/browse:media:imgur [ Skip ]
+crbug.com/964804 [ Nexus_5X ] system_health.memory_mobile/browse:media:facebook_photos [ Skip ]
+crbug.com/964804 [ Nexus_5X ] system_health.memory_mobile/browse:media:youtube [ Skip ]
+crbug.com/964804 [ Nexus_5X ] system_health.memory_mobile/browse:shopping:lazada [ Skip ]
+crbug.com/964804 [ Nexus_5X ] system_health.memory_mobile/browse:tools:maps [ Skip ]
+crbug.com/964804 [ Nexus_5X ] system_health.memory_mobile/load:media:dailymotion [ Skip ]
+crbug.com/964804 [ Nexus_5X ] system_health.memory_mobile/load:news:qq [ Skip ]
+crbug.com/964804 [ Nexus_5X ] system_health.memory_mobile/load:news:wikipedia:2018 [ Skip ]
+crbug.com/964804 [ Nexus_5X ] system_health.memory_mobile/load:search:ebay:2018 [ Skip ]
+crbug.com/964804 [ Nexus_5X ] system_health.memory_mobile/load:search:taobao [ Skip ]
+crbug.com/964804 [ Nexus_5X ] system_health.memory_mobile/load:tools:dropbox [ Skip ]
+
 # Benchmark: tab_switching.typical_25
 crbug.com/747026 [ Mac ] tab_switching.typical_25/multitab:misc:typical24 [ Skip ]
 crbug.com/883731 [ Win ] tab_switching.typical_25/multitab:misc:typical24 [ Skip ]
diff --git a/tools/perf/page_sets/rendering/key_silk_cases.py b/tools/perf/page_sets/rendering/key_silk_cases.py
index 3218b1cb..1d59005 100644
--- a/tools/perf/page_sets/rendering/key_silk_cases.py
+++ b/tools/perf/page_sets/rendering/key_silk_cases.py
@@ -335,7 +335,6 @@
 
   BASE_NAME = 'swipe_action'
   URL = 'file://../key_silk_cases/inbox_app.html?swipe_to_dismiss'
-  TAGS = KeySilkPage.TAGS + [story_tags.REPRESENTATIVE_MOBILE]
 
   def SwipeToDismiss(self, action_runner):
     with action_runner.CreateGestureInteraction('SwipeAction'):
@@ -643,7 +642,6 @@
 
   BASE_NAME = 'silk_finance'
   URL = 'file://../key_silk_cases/silk_finance.html'
-  TAGS = KeySilkPage.TAGS + [story_tags.REPRESENTATIVE_MOBILE]
 
   def PerformPageInteractions(self, action_runner):
     with action_runner.CreateInteraction('animation_interaction'):
diff --git a/tools/perf/page_sets/rendering/maps.py b/tools/perf/page_sets/rendering/maps.py
index 932e538..4e04c09 100644
--- a/tools/perf/page_sets/rendering/maps.py
+++ b/tools/perf/page_sets/rendering/maps.py
@@ -25,7 +25,8 @@
 """
   BASE_NAME = 'maps_perf_test'
   URL = 'file://performance.html'
-  TAGS = [story_tags.REQUIRED_WEBGL, story_tags.MAPS]
+  TAGS = [story_tags.REQUIRED_WEBGL, story_tags.MAPS,
+    story_tags.REPRESENTATIVE_MOBILE]
 
   def __init__(self,
                page_set,
diff --git a/tools/perf/page_sets/rendering/motionmark.py b/tools/perf/page_sets/rendering/motionmark.py
index 137c1a9..3af6dcf 100644
--- a/tools/perf/page_sets/rendering/motionmark.py
+++ b/tools/perf/page_sets/rendering/motionmark.py
@@ -67,7 +67,6 @@
 class MotionmarkAnimMultiply175(MotionMarkPage):
   BASE_NAME = 'motionmark_anim_multiply_175'
   URL = MotionMarkPage.GetUrl('Animometer', 'Multiply', 175)
-  TAGS = MotionMarkPage.TAGS + [story_tags.REPRESENTATIVE_MOBILE]
 
 
 # Why: MotionMark Animometer case """
diff --git a/tools/perf/page_sets/rendering/top_real_world_desktop.py b/tools/perf/page_sets/rendering/top_real_world_desktop.py
index 82df6de..0667a276 100644
--- a/tools/perf/page_sets/rendering/top_real_world_desktop.py
+++ b/tools/perf/page_sets/rendering/top_real_world_desktop.py
@@ -85,7 +85,6 @@
   BASE_NAME = 'google_plus'
   YEAR = '2018'
   URL = 'https://plus.google.com/110031535020051778989/posts'
-  TAGS = TopRealWorldDesktopPage.TAGS + [story_tags.REPRESENTATIVE_MOBILE]
 
   def __init__(self,
                page_set,
@@ -180,7 +179,6 @@
   BASE_NAME = 'facebook'
   YEAR = '2018'
   URL = 'https://www.facebook.com/barackobama'
-  TAGS = TopRealWorldDesktopPage.TAGS + [story_tags.REPRESENTATIVE_MOBILE]
 
   def __init__(self,
                page_set,
@@ -430,6 +428,7 @@
   BASE_NAME = 'yahoo_news'
   YEAR = '2018'
   URL = 'http://news.yahoo.com'
+  TAGS = TopRealWorldDesktopPage.TAGS + [story_tags.REPRESENTATIVE_MOBILE]
 
 
 class CNNNews2018Page(TopRealWorldDesktopPage):
diff --git a/tools/perf/page_sets/rendering/tough_animation_cases.py b/tools/perf/page_sets/rendering/tough_animation_cases.py
index 11ded6d..ad66356 100644
--- a/tools/perf/page_sets/rendering/tough_animation_cases.py
+++ b/tools/perf/page_sets/rendering/tough_animation_cases.py
@@ -196,7 +196,6 @@
   BASE_NAME = 'css_transitions_triggered_updating_class'
   # pylint: disable=line-too-long
   URL = 'file://../tough_animation_cases/css_transitions_staggered_triggering_by_updating_class.html?N=0316'
-  TAGS = ToughAnimationPage.TAGS + [story_tags.REPRESENTATIVE_MOBILE]
 
 
 class CssTransitionsTriggeredInlineStylePage(ToughAnimationPage):
@@ -215,7 +214,6 @@
   BASE_NAME = 'css_animations_many_keyframes'
   # pylint: disable=line-too-long
   URL = 'file://../tough_animation_cases/css_animations_many_keyframes.html?N=0316'
-  TAGS = ToughAnimationPage.TAGS + [story_tags.REPRESENTATIVE_MOBILE]
 
 
 class CssAnimationsSimultaneousNewElementPage(ToughAnimationPage):
@@ -243,7 +241,6 @@
   BASE_NAME = 'css_animations_simultaneous_updating_class'
   # pylint: disable=line-too-long
   URL = 'file://../tough_animation_cases/css_animations_simultaneous_by_updating_class.html?N=0316'
-  TAGS = ToughAnimationPage.TAGS + [story_tags.REPRESENTATIVE_MOBILE]
 
 
 class CssAnimationsSimultaneousInlineStylePage(ToughAnimationPage):
@@ -317,7 +314,6 @@
   BASE_NAME = 'css_animations_triggered_style_element'
   # pylint: disable=line-too-long
   URL = 'file://../tough_animation_cases/css_animations_staggered_triggering_by_inserting_style_element.html?N=0316'
-  TAGS = ToughAnimationPage.TAGS + [story_tags.REPRESENTATIVE_MOBILE]
 
 
 class CssAnimationsTriggeredUpdatingClassPage(ToughAnimationPage):
diff --git a/tools/perf/page_sets/rendering/tough_canvas_cases.py b/tools/perf/page_sets/rendering/tough_canvas_cases.py
index 41e573d..19e8cd0 100644
--- a/tools/perf/page_sets/rendering/tough_canvas_cases.py
+++ b/tools/perf/page_sets/rendering/tough_canvas_cases.py
@@ -41,6 +41,7 @@
 class GeoAPIsPage(ToughCanvasPage):
   BASE_NAME = 'geo_apis'
   URL = 'http://geoapis.appspot.com/agdnZW9hcGlzchMLEgtFeGFtcGxlQ29kZRjh1wIM'
+  TAGS = ToughCanvasPage.TAGS + [story_tags.REPRESENTATIVE_MOBILE]
 
 
 class RunwayPage(ToughCanvasPage):
@@ -64,6 +65,7 @@
 class Kevs3DPage(ToughCanvasPage):
   BASE_NAME = 'kevs_3d'
   URL = 'http://www.kevs3d.co.uk/dev/canvask3d/k3d_test.html'
+  TAGS = ToughCanvasPage.TAGS + [story_tags.REPRESENTATIVE_MOBILE]
 
 
 class MegiDishPage(ToughCanvasPage):
@@ -144,13 +146,15 @@
 class SmashCatPage(ToughCanvasPage):
   BASE_NAME = 'smash_cat'
   URL = 'http://www.smashcat.org/av/canvas_test/'
-  TAGS = ToughCanvasPage.TAGS + [story_tags.REPRESENTATIVE_MAC_DESKTOP]
+  TAGS = ToughCanvasPage.TAGS + [story_tags.REPRESENTATIVE_MAC_DESKTOP,
+    story_tags.REPRESENTATIVE_MOBILE]
 
 
 class BouncingBallsShadowPage(ToughCanvasPage):
   BASE_NAME = 'bouncing_balls_shadow'
   # pylint: disable=line-too-long
   URL = 'file://../tough_canvas_cases/canvas2d_balls_common/bouncing_balls.html?ball=image_with_shadow&back=image'
+  TAGS = ToughCanvasPage.TAGS + [story_tags.REPRESENTATIVE_MOBILE]
 
 
 class BouncingBalls15Page(ToughCanvasPage):
@@ -167,8 +171,7 @@
 class CanvasAnimationNoClearPage(ToughCanvasPage):
   BASE_NAME = 'canvas_animation_no_clear'
   URL = 'file://../tough_canvas_cases/canvas-animation-no-clear.html'
-  TAGS = ToughCanvasPage.TAGS + [story_tags.REPRESENTATIVE_MAC_DESKTOP,
-    story_tags.REPRESENTATIVE_MOBILE]
+  TAGS = ToughCanvasPage.TAGS + [story_tags.REPRESENTATIVE_MAC_DESKTOP]
 
 
 class CanvasToBlobPage(ToughCanvasPage):
@@ -189,8 +192,7 @@
 class CanvasLinesPage(ToughCanvasPage):
   BASE_NAME = 'canvas_lines'
   URL = 'file://../tough_canvas_cases/rendering_throughput/canvas_lines.html'
-  TAGS = ToughCanvasPage.TAGS + [story_tags.REPRESENTATIVE_MAC_DESKTOP,
-    story_tags.REPRESENTATIVE_MOBILE]
+  TAGS = ToughCanvasPage.TAGS + [story_tags.REPRESENTATIVE_MAC_DESKTOP]
 
 
 class PutGetImageDataPage(ToughCanvasPage):
diff --git a/tools/perf/page_sets/rendering/tough_compositor_cases.py b/tools/perf/page_sets/rendering/tough_compositor_cases.py
index 2694e4d..964588b 100644
--- a/tools/perf/page_sets/rendering/tough_compositor_cases.py
+++ b/tools/perf/page_sets/rendering/tough_compositor_cases.py
@@ -235,8 +235,6 @@
   SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY
   URL = ('file://../../../../chrome/test/data/perf/tough_compositor_cases/'
          'infinite_scroll_element_n_layers.html?layer_count=53')
-  TAGS = InfiniteScrollElementNLayersPage.TAGS + [
-    story_tags.REPRESENTATIVE_MOBILE]
 
 
 # Why: Infinite non-root scroller with 95%-ile layer count"""
@@ -309,8 +307,6 @@
   SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY
   URL = ('file://../../../../chrome/test/data/perf/tough_compositor_cases/'
          'infinite_scroll_root_fixed_n_layers.html?layer_count=1')
-  TAGS = InfiniteScrollRootNLayersPage.TAGS + [
-    story_tags.REPRESENTATIVE_MOBILE]
 
 
 # Why: Infinite root scroller + fixed element, with 50%-ile layer count"""
diff --git a/tools/perf/page_sets/rendering/tough_filters_cases.py b/tools/perf/page_sets/rendering/tough_filters_cases.py
index ffa2bc63..be33a829 100644
--- a/tools/perf/page_sets/rendering/tough_filters_cases.py
+++ b/tools/perf/page_sets/rendering/tough_filters_cases.py
@@ -42,6 +42,8 @@
   URL = ('http://web.archive.org/web/20150502135732/'
          'http://ie.microsoft.com/testdrive/Performance/'
          'Pirates/Default.html')
+  TAGS = rendering_story.RenderingStory.TAGS + [
+    story_tags.REPRESENTATIVE_MOBILE]
 
   def __init__(self,
                page_set,
diff --git a/tools/perf/page_sets/rendering/tough_pinch_zoom_mobile_cases.py b/tools/perf/page_sets/rendering/tough_pinch_zoom_mobile_cases.py
index 77c6370..ea4c8a8e 100644
--- a/tools/perf/page_sets/rendering/tough_pinch_zoom_mobile_cases.py
+++ b/tools/perf/page_sets/rendering/tough_pinch_zoom_mobile_cases.py
@@ -58,6 +58,7 @@
   BASE_NAME = 'linkedin_mobile_pinch'
   YEAR = '2018'
   URL = 'http://www.linkedin.com/in/linustorvalds'
+  TAGS = ToughPinchZoomMobilePage.TAGS + [story_tags.REPRESENTATIVE_MOBILE]
 
   # Linkedin has expensive shader compilation so it can benefit from shader
   # cache from reload.
@@ -88,7 +89,6 @@
   BASE_NAME = 'cnn_mobile_pinch'
   YEAR = '2018'
   URL = 'http://www.cnn.com/travel/article/airbus-a330-900-neo-tours-us-airports/index.html'
-  TAGS = ToughPinchZoomMobilePage.TAGS + [story_tags.REPRESENTATIVE_MOBILE]
 
 
 class EBayPinchZoomMobile2018Page(ToughPinchZoomMobilePage):
diff --git a/tools/perf/page_sets/rendering/tough_scrolling_cases.py b/tools/perf/page_sets/rendering/tough_scrolling_cases.py
index d4881ac..451f743 100644
--- a/tools/perf/page_sets/rendering/tough_scrolling_cases.py
+++ b/tools/perf/page_sets/rendering/tough_scrolling_cases.py
@@ -177,6 +177,7 @@
   BASE_NAME = 'canvas_10000_pixels_per_second'
   URL = 'file://../tough_scrolling_cases/canvas.html'
   SPEED_IN_PIXELS_PER_SECOND = 10000
+  TAGS = ToughFastScrollingPage.TAGS + [story_tags.REPRESENTATIVE_MOBILE]
 
 
 class ScrollingCanvas20000Page(ToughFastScrollingPage):
@@ -190,6 +191,7 @@
   BASE_NAME = 'canvas_40000_pixels_per_second'
   URL = 'file://../tough_scrolling_cases/canvas.html'
   SPEED_IN_PIXELS_PER_SECOND = 40000
+  TAGS = ToughFastScrollingPage.TAGS + [story_tags.REPRESENTATIVE_MOBILE]
 
 
 class ScrollingCanvas60000Page(ToughFastScrollingPage):
@@ -202,6 +204,7 @@
   BASE_NAME = 'canvas_75000_pixels_per_second'
   URL = 'file://../tough_scrolling_cases/canvas.html'
   SPEED_IN_PIXELS_PER_SECOND = 75000
+  TAGS = ToughFastScrollingPage.TAGS + [story_tags.REPRESENTATIVE_MOBILE]
 
 
 class ScrollingCanvas90000Page(ToughFastScrollingPage):
diff --git a/tools/perf/page_sets/rendering/tough_texture_upload_cases.py b/tools/perf/page_sets/rendering/tough_texture_upload_cases.py
index 49a2bef..2b350b2 100644
--- a/tools/perf/page_sets/rendering/tough_texture_upload_cases.py
+++ b/tools/perf/page_sets/rendering/tough_texture_upload_cases.py
@@ -42,7 +42,6 @@
 class SmallTextureUploadsPage(ToughTextureUploadPage):
   BASE_NAME = 'small_texture_uploads'
   URL = 'file://../tough_texture_upload_cases/small_texture_uploads.html'
-  TAGS = ToughTextureUploadPage.TAGS + [story_tags.REPRESENTATIVE_MOBILE]
 
 
 class MediumTextureUploadsPage(ToughTextureUploadPage):
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn
index 13e6a94..20371e7 100644
--- a/ui/base/BUILD.gn
+++ b/ui/base/BUILD.gn
@@ -109,16 +109,12 @@
     "cocoa/focus_window_set.mm",
     "cocoa/menu_controller.h",
     "cocoa/menu_controller.mm",
-    "cocoa/ns_view_ids.h",
-    "cocoa/ns_view_ids.mm",
     "cocoa/quartz_util.h",
     "cocoa/quartz_util.mm",
     "cocoa/remote_accessibility_api.h",
     "cocoa/remote_accessibility_api.mm",
     "cocoa/remote_layer_api.h",
     "cocoa/remote_layer_api.mm",
-    "cocoa/remote_views_window.h",
-    "cocoa/remote_views_window.mm",
     "cocoa/secure_password_input.h",
     "cocoa/secure_password_input.mm",
     "cocoa/text_services_context_menu.cc",
diff --git a/ui/base/cocoa/ns_view_ids.h b/ui/base/cocoa/ns_view_ids.h
deleted file mode 100644
index 749fdd1..0000000
--- a/ui/base/cocoa/ns_view_ids.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2018 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.
-
-#ifndef UI_BASE_COCOA_NS_VIEW_IDS_H_
-#define UI_BASE_COCOA_NS_VIEW_IDS_H_
-
-#include <stdint.h>
-
-#include "base/macros.h"
-#include "ui/base/ui_base_export.h"
-
-@class NSView;
-
-namespace ui {
-
-// A class used to manage NSViews across processes.
-// - NSViews that may be instantiated in another process are assigned an id in
-//   the browser process.
-// - Instantiating a ScopedNSViewIdMapping in the process where the NSView is
-//   created will make NSViewIds::GetNSView return the specified NSView.
-// - This mechanism is used by mojo methods to refer to NSViews across
-//   interfaces (in particular, to specify parent NSViews).
-class UI_BASE_EXPORT NSViewIds {
- public:
-  // Get a new id to use with a new NSView. This is to only be called in the
-  // browser process.
-  static uint64_t GetNewId();
-
-  // Return an NSView given its id. This is to be called in an app shim process.
-  static NSView* GetNSView(uint64_t ns_view_id);
-};
-
-// A scoped mapping from |ns_view_id| to |view|. While this object exists,
-// NSViewIds::GetNSView will return |view| when queried with |ns_view_id|. This
-// is to be instantiated in the app shim process.
-class UI_BASE_EXPORT ScopedNSViewIdMapping {
- public:
-  ScopedNSViewIdMapping(uint64_t ns_view_id, NSView* view);
-  ~ScopedNSViewIdMapping();
-
- private:
-  const uint64_t ns_view_id_;
-  DISALLOW_COPY_AND_ASSIGN(ScopedNSViewIdMapping);
-};
-
-}  // namespace ui
-
-#endif  // UI_BASE_COCOA_NS_VIEW_IDS_H_
diff --git a/ui/base/cocoa/remote_views_window.h b/ui/base/cocoa/remote_views_window.h
deleted file mode 100644
index 634d54a9..0000000
--- a/ui/base/cocoa/remote_views_window.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2018 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.
-
-#ifndef UI_BASE_COCOA_REMOTE_VIEWS_WINDOW_H_
-#define UI_BASE_COCOA_REMOTE_VIEWS_WINDOW_H_
-
-#include "ui/base/ui_base_export.h"
-#include "ui/gfx/native_widget_types.h"
-
-namespace ui {
-
-// Returns true if the specified NSWindow corresponds to an NSWindow that is
-// being viewed in a remote process.
-bool UI_BASE_EXPORT IsWindowUsingRemoteViews(gfx::NativeWindow window);
-
-// Create a transparent NSWindow that is in the same position as |window|,
-// but is at the ModalPanel window level, so that it will appear over all
-// other window.
-NSWindow* UI_BASE_EXPORT
-CreateTransparentRemoteViewsClone(gfx::NativeWindow window);
-
-}  // namespace ui
-
-#endif  // UI_BASE_COCOA_REMOTE_VIEWS_WINDOW_H_
diff --git a/ui/compositor/layer.cc b/ui/compositor/layer.cc
index 3a2da7e..316f96f 100644
--- a/ui/compositor/layer.cc
+++ b/ui/compositor/layer.cc
@@ -1182,7 +1182,7 @@
 }
 
 std::unique_ptr<base::trace_event::TracedValue> Layer::TakeDebugInfo(
-    cc::Layer* layer) {
+    const cc::Layer* layer) {
   auto value = std::make_unique<base::trace_event::TracedValue>();
   value->SetString("layer_name", name_);
   return value;
diff --git a/ui/compositor/layer.h b/ui/compositor/layer.h
index 345bf4fb..60ec24e 100644
--- a/ui/compositor/layer.h
+++ b/ui/compositor/layer.h
@@ -442,7 +442,7 @@
 
   // LayerClient implementation.
   std::unique_ptr<base::trace_event::TracedValue> TakeDebugInfo(
-      cc::Layer* layer) override;
+      const cc::Layer* layer) override;
   void DidChangeScrollbarsHiddenIfOverlay(bool) override;
 
   // Triggers a call to SwitchToLayer.
diff --git a/ui/display/manager/apply_content_protection_task.cc b/ui/display/manager/apply_content_protection_task.cc
index 89f73ca..43ad7ff 100644
--- a/ui/display/manager/apply_content_protection_task.cc
+++ b/ui/display/manager/apply_content_protection_task.cc
@@ -15,25 +15,6 @@
 
 namespace display {
 
-namespace {
-
-bool GetHDCPCapableDisplays(
-    const DisplayLayoutManager& layout_manager,
-    std::vector<DisplaySnapshot*>* hdcp_capable_displays) {
-  for (DisplaySnapshot* display : layout_manager.GetDisplayStates()) {
-    uint32_t protection_mask;
-    if (!GetContentProtectionMethods(display->type(), &protection_mask))
-      return false;
-
-    if (protection_mask & CONTENT_PROTECTION_METHOD_HDCP)
-      hdcp_capable_displays->push_back(display);
-  }
-
-  return true;
-}
-
-}  // namespace
-
 ApplyContentProtectionTask::ApplyContentProtectionTask(
     DisplayLayoutManager* layout_manager,
     NativeDisplayDelegate* native_display_delegate,
@@ -51,9 +32,15 @@
 
 void ApplyContentProtectionTask::Run() {
   std::vector<DisplaySnapshot*> hdcp_capable_displays;
-  if (!GetHDCPCapableDisplays(*layout_manager_, &hdcp_capable_displays)) {
-    std::move(callback_).Run(Status::FAILURE);
-    return;
+  for (DisplaySnapshot* display : layout_manager_->GetDisplayStates()) {
+    uint32_t protection_mask;
+    if (!GetContentProtectionMethods(display->type(), &protection_mask)) {
+      std::move(callback_).Run(Status::FAILURE);
+      return;
+    }
+
+    if (protection_mask & CONTENT_PROTECTION_METHOD_HDCP)
+      hdcp_capable_displays.push_back(display);
   }
 
   pending_requests_ = hdcp_capable_displays.size();
@@ -66,17 +53,25 @@
   // updated the state.
   for (DisplaySnapshot* display : hdcp_capable_displays) {
     native_display_delegate_->GetHDCPState(
-        *display,
-        base::BindOnce(&ApplyContentProtectionTask::OnGetHDCPState,
-                       weak_ptr_factory_.GetWeakPtr(), display->display_id()));
+        *display, base::BindOnce(&ApplyContentProtectionTask::OnGetHDCPState,
+                                 weak_ptr_factory_.GetWeakPtr(), display));
   }
 }
 
-void ApplyContentProtectionTask::OnGetHDCPState(int64_t display_id,
+void ApplyContentProtectionTask::OnGetHDCPState(DisplaySnapshot* display,
                                                 bool success,
                                                 HDCPState state) {
   success_ &= success;
-  hdcp_states_[display_id] = state;
+
+  bool hdcp_enabled = state != HDCP_STATE_UNDESIRED;
+  bool hdcp_requested = GetDesiredProtectionMask(display->display_id()) &
+                        CONTENT_PROTECTION_METHOD_HDCP;
+
+  if (hdcp_enabled != hdcp_requested) {
+    hdcp_requests_.emplace_back(
+        display, hdcp_requested ? HDCP_STATE_DESIRED : HDCP_STATE_UNDESIRED);
+  }
+
   pending_requests_--;
 
   // Wait for all the requests before continuing.
@@ -88,37 +83,7 @@
     return;
   }
 
-  ApplyProtections();
-}
-
-void ApplyContentProtectionTask::ApplyProtections() {
-  std::vector<DisplaySnapshot*> hdcp_capable_displays;
-  if (!GetHDCPCapableDisplays(*layout_manager_, &hdcp_capable_displays)) {
-    std::move(callback_).Run(Status::FAILURE);
-    return;
-  }
-
-  std::vector<std::pair<DisplaySnapshot*, HDCPState>> hdcp_requests;
-  // Figure out which displays need to have their HDCP state changed.
-  for (DisplaySnapshot* display : hdcp_capable_displays) {
-    uint32_t desired_mask = GetDesiredProtectionMask(display->display_id());
-
-    auto it = hdcp_states_.find(display->display_id());
-    // If the display can't be found, the display configuration changed.
-    if (it == hdcp_states_.end()) {
-      std::move(callback_).Run(Status::FAILURE);
-      return;
-    }
-
-    bool hdcp_enabled = it->second != HDCP_STATE_UNDESIRED;
-    bool hdcp_requested = desired_mask & CONTENT_PROTECTION_METHOD_HDCP;
-    if (hdcp_enabled != hdcp_requested) {
-      hdcp_requests.emplace_back(
-          display, hdcp_requested ? HDCP_STATE_DESIRED : HDCP_STATE_UNDESIRED);
-    }
-  }
-
-  pending_requests_ = hdcp_requests.size();
+  pending_requests_ = hdcp_requests_.size();
   // All the requested changes are the same as the current HDCP state. Nothing
   // to do anymore, just ack the content protection change.
   if (pending_requests_ == 0) {
@@ -126,7 +91,7 @@
     return;
   }
 
-  for (const auto& pair : hdcp_requests) {
+  for (const auto& pair : hdcp_requests_) {
     native_display_delegate_->SetHDCPState(
         *pair.first, pair.second,
         base::BindOnce(&ApplyContentProtectionTask::OnSetHDCPState,
diff --git a/ui/display/manager/apply_content_protection_task.h b/ui/display/manager/apply_content_protection_task.h
index e038eab3..89bcabf 100644
--- a/ui/display/manager/apply_content_protection_task.h
+++ b/ui/display/manager/apply_content_protection_task.h
@@ -7,8 +7,8 @@
 
 #include <cstddef>
 #include <cstdint>
+#include <vector>
 
-#include "base/containers/flat_map.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "ui/display/manager/display_configurator.h"
@@ -18,25 +18,13 @@
 class DisplayLayoutManager;
 class NativeDisplayDelegate;
 
-// In order to apply content protection the task executes in the following
-// manner:
-// 1) Run()
-//   a) Query NativeDisplayDelegate for HDCP state on capable displays
-//   b) OnGetHDCPState() called for each display as response to (a)
-// 2) ApplyProtections()
-//   a) Compute preferred HDCP state for capable displays
-//   b) Call into NativeDisplayDelegate to set HDCP state on capable displays
-//   c) OnSetHDCPState() called for each display as response to (b)
-// 3) Call |callback_| to signal end of task.
-//
-// Note, in steps 1a and 2a, if no HDCP capable displays are found or if errors
-// are reported, the task finishes early and skips to step 3.
 class DISPLAY_MANAGER_EXPORT ApplyContentProtectionTask
     : public DisplayConfigurator::ContentProtectionTask {
  public:
   using ResponseCallback = base::OnceCallback<void(Status)>;
 
-  // The task disables protection on displays omitted from |requests|.
+  // The task disables protection on displays omitted from |requests|. Note that
+  // pending tasks are killed on display reconfiguration.
   ApplyContentProtectionTask(DisplayLayoutManager* layout_manager,
                              NativeDisplayDelegate* native_display_delegate,
                              DisplayConfigurator::ContentProtections requests,
@@ -46,11 +34,9 @@
   void Run() override;
 
  private:
-  void OnGetHDCPState(int64_t display_id, bool success, HDCPState state);
+  void OnGetHDCPState(DisplaySnapshot* display, bool success, HDCPState state);
   void OnSetHDCPState(bool success);
 
-  void ApplyProtections();
-
   uint32_t GetDesiredProtectionMask(int64_t display_id) const;
 
   DisplayLayoutManager* const layout_manager_;            // Not owned.
@@ -59,7 +45,7 @@
   const DisplayConfigurator::ContentProtections requests_;
   ResponseCallback callback_;
 
-  base::flat_map<int64_t /* display_id */, HDCPState> hdcp_states_;
+  std::vector<std::pair<DisplaySnapshot*, HDCPState>> hdcp_requests_;
 
   bool success_ = true;
   size_t pending_requests_ = 0;
diff --git a/ui/display/manager/display_configurator.cc b/ui/display/manager/display_configurator.cc
index 0f99fc2..99e43106 100644
--- a/ui/display/manager/display_configurator.cc
+++ b/ui/display/manager/display_configurator.cc
@@ -13,6 +13,7 @@
 #include "base/command_line.h"
 #include "base/logging.h"
 #include "base/macros.h"
+#include "base/stl_util.h"
 #include "base/time/time.h"
 #include "chromeos/system/devicemode.h"
 #include "ui/display/display.h"
@@ -1175,6 +1176,15 @@
     if (!configure_timer_.IsRunning())
       CallAndClearQueuedCallbacks(success);
   }
+
+  // Filter out content protection requests for removed displays.
+  for (auto& requests : content_protection_requests_) {
+    base::EraseIf(requests.second,
+                  [this](const auto& pair) { return !GetDisplay(pair.first); });
+  }
+
+  // Kill tasks to fire failure callbacks.
+  content_protection_tasks_ = {};
 }
 
 void DisplayConfigurator::UpdatePowerState(
diff --git a/ui/display/manager/display_configurator_unittest.cc b/ui/display/manager/display_configurator_unittest.cc
index 4816ed20..d4fb1b21 100644
--- a/ui/display/manager/display_configurator_unittest.cc
+++ b/ui/display/manager/display_configurator_unittest.cc
@@ -1083,6 +1083,45 @@
   EXPECT_EQ(HDCP_STATE_UNDESIRED, native_display_delegate_->hdcp_state());
 }
 
+TEST_F(DisplayConfiguratorTest, ContentProtectionTasksKilledOnConfigure) {
+  InitWithOutputs(&small_mode_, &big_mode_);
+
+  auto id = configurator_.RegisterContentProtectionClient();
+  EXPECT_TRUE(id);
+
+  native_display_delegate_->set_run_async(true);
+
+  configurator_.ApplyContentProtection(
+      id, outputs_[1]->display_id(), CONTENT_PROTECTION_METHOD_HDCP,
+      base::BindOnce(&DisplayConfiguratorTest::ApplyContentProtectionCallback,
+                     base::Unretained(this)));
+
+  configurator_.QueryContentProtection(
+      id, outputs_[1]->display_id(),
+      base::BindOnce(&DisplayConfiguratorTest::QueryContentProtectionCallback,
+                     base::Unretained(this)));
+
+  native_display_delegate_->set_run_async(false);
+  configurator_.OnConfigurationChanged();
+  EXPECT_TRUE(test_api_.TriggerConfigureTimeout());
+  log_->GetActionsAndClear();
+
+  base::RunLoop().RunUntilIdle();
+
+  // Configuration change should kill tasks and trigger failure callbacks.
+  EXPECT_EQ(1, apply_content_protection_call_count_);
+  EXPECT_FALSE(apply_content_protection_success_);
+
+  EXPECT_EQ(1, query_content_protection_call_count_);
+  EXPECT_FALSE(query_content_protection_success_);
+  EXPECT_EQ(DISPLAY_CONNECTION_TYPE_NONE, connection_mask_);
+  EXPECT_EQ(CONTENT_PROTECTION_METHOD_NONE, protection_mask_);
+
+  // Pending task to enable protection should have been killed.
+  EXPECT_EQ(kNoActions, log_->GetActionsAndClear());
+  EXPECT_EQ(HDCP_STATE_UNDESIRED, native_display_delegate_->hdcp_state());
+}
+
 TEST_F(DisplayConfiguratorTest, DoNotConfigureWithSuspendedDisplays) {
   InitWithOutputs(&small_mode_);
 
diff --git a/ui/display/manager/query_content_protection_task.cc b/ui/display/manager/query_content_protection_task.cc
index f81c28d..8488b96 100644
--- a/ui/display/manager/query_content_protection_task.cc
+++ b/ui/display/manager/query_content_protection_task.cc
@@ -34,7 +34,8 @@
 void QueryContentProtectionTask::Run() {
   std::vector<DisplaySnapshot*> hdcp_capable_displays;
   for (DisplaySnapshot* display : layout_manager_->GetDisplayStates()) {
-    // Query display if it is in mirror mode or client on the same display.
+    // Query all displays in mirroring mode. Otherwise, query the given display,
+    // which must exist because tasks are killed on display reconfiguration.
     if (!layout_manager_->IsMirroring() && display->display_id() != display_id_)
       continue;
 
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn
index f9a87d5..c667f5a 100644
--- a/ui/gfx/BUILD.gn
+++ b/ui/gfx/BUILD.gn
@@ -267,7 +267,7 @@
     "//third_party/zlib",
   ]
 
-  if (is_linux || is_android || is_fuchsia) {
+  if (!is_mac && !is_ios) {
     sources += [
       "platform_font_skia.cc",
       "platform_font_skia.h",
diff --git a/ui/gfx/font_render_params.h b/ui/gfx/font_render_params.h
index 9c7491e..29d81b9 100644
--- a/ui/gfx/font_render_params.h
+++ b/ui/gfx/font_render_params.h
@@ -117,7 +117,8 @@
 GFX_EXPORT void ClearFontRenderParamsCacheForTest();
 #endif
 
-#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_FUCHSIA)
+#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_ANDROID) || \
+    defined(OS_FUCHSIA)
 // Gets the device scale factor to query the FontRenderParams.
 GFX_EXPORT float GetFontRenderParamsDeviceScaleFactor();
 
diff --git a/ui/gfx/font_render_params_win.cc b/ui/gfx/font_render_params_win.cc
index 1fddb126..6693f3af 100644
--- a/ui/gfx/font_render_params_win.cc
+++ b/ui/gfx/font_render_params_win.cc
@@ -113,4 +113,8 @@
   return CachedFontRenderParams::GetInstance()->GetParams();
 }
 
+float GetFontRenderParamsDeviceScaleFactor() {
+  return 1.;
+}
+
 }  // namespace gfx
diff --git a/ui/gfx/platform_font_skia.cc b/ui/gfx/platform_font_skia.cc
index 4498efa5..46e6167 100644
--- a/ui/gfx/platform_font_skia.cc
+++ b/ui/gfx/platform_font_skia.cc
@@ -338,6 +338,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 // PlatformFont, public:
 
+#if !defined(OS_WIN)
 // static
 PlatformFont* PlatformFont::CreateDefault() {
   return new PlatformFontSkia;
@@ -349,5 +350,6 @@
   TRACE_EVENT0("fonts", "PlatformFont::CreateFromNameAndSize");
   return new PlatformFontSkia(font_name, font_size);
 }
+#endif  // !defined(OS_WIN)
 
 }  // namespace gfx
diff --git a/ui/gfx/platform_font_win.cc b/ui/gfx/platform_font_win.cc
index eb18954..478e45e 100644
--- a/ui/gfx/platform_font_win.cc
+++ b/ui/gfx/platform_font_win.cc
@@ -17,6 +17,7 @@
 
 #include "base/containers/flat_map.h"
 #include "base/debug/alias.h"
+#include "base/feature_list.h"
 #include "base/logging.h"
 #include "base/no_destructor.h"
 #include "base/stl_util.h"
@@ -36,12 +37,17 @@
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/font.h"
 #include "ui/gfx/font_render_params.h"
+#include "ui/gfx/platform_font_skia.h"
 #include "ui/gfx/system_fonts_win.h"
 #include "ui/gfx/win/direct_write.h"
 #include "ui/gfx/win/scoped_set_map_mode.h"
 
 namespace {
 
+// Enable the use of PlatformFontSkia instead of PlatformFontWin.
+const base::Feature kPlatformFontSkiaOnWindows{
+    "PlatformFontSkiaOnWindows", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Sets style properties on |font_info| based on |font_style|.
 void SetLogFontStyle(int font_style, LOGFONT* font_info) {
   font_info->lfUnderline = (font_style & gfx::Font::UNDERLINE) != 0;
@@ -625,6 +631,8 @@
 
 // static
 PlatformFont* PlatformFont::CreateDefault() {
+  if (base::FeatureList::IsEnabled(kPlatformFontSkiaOnWindows))
+    return new PlatformFontSkia;
   return new PlatformFontWin;
 }
 
@@ -632,6 +640,8 @@
 PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string& font_name,
                                                   int font_size) {
   TRACE_EVENT0("fonts", "PlatformFont::CreateFromNameAndSize");
+  if (base::FeatureList::IsEnabled(kPlatformFontSkiaOnWindows))
+    return new PlatformFontSkia(font_name, font_size);
   return new PlatformFontWin(font_name, font_size);
 }
 
diff --git a/ui/gl/gl_surface_egl.cc b/ui/gl/gl_surface_egl.cc
index f927f86e..bb775f34 100644
--- a/ui/gl/gl_surface_egl.cc
+++ b/ui/gl/gl_surface_egl.cc
@@ -1477,6 +1477,15 @@
   // reporting purpose.
   std::vector<EGLnsecsANDROID> egl_timestamps(supported_egl_timestamps_.size(),
                                               EGL_TIMESTAMP_INVALID_ANDROID);
+
+  // TODO(vikassoni): File a driver bug for eglGetFrameTimestampsANDROID().
+  // See https://bugs.chromium.org/p/chromium/issues/detail?id=966638.
+  // As per the spec, the driver is expected to return a valid timestamp from
+  // the call eglGetFrameTimestampsANDROID() when its not
+  // EGL_TIMESTAMP_PENDING_ANDROID or EGL_TIMESTAMP_INVALID_ANDROID. But
+  // currently some buggy drivers an invalid timestamp 0.
+  // This is currentlt handled in chrome for by setting the presentation time to
+  // TimeTicks::Now() (snapped to the next vsync) instead of 0.
   if ((frame_id < 0) ||
       !eglGetFrameTimestampsANDROID(
           GetDisplay(), surface_, frame_id,
@@ -1512,7 +1521,6 @@
                          base::TimeDelta::FromNanoseconds(presentation_time_ns);
     *presentation_flags = presentation_flags_;
   }
-  DCHECK(!presentation_time->is_null());
   return true;
 }
 
diff --git a/ui/gl/gl_surface_presentation_helper.cc b/ui/gl/gl_surface_presentation_helper.cc
index e7bcd1a..f7e6ae11 100644
--- a/ui/gl/gl_surface_presentation_helper.cc
+++ b/ui/gl/gl_surface_presentation_helper.cc
@@ -70,8 +70,24 @@
   DCHECK(frame.timer || frame.fence || egl_timestamp_client_);
 
   if (egl_timestamp_client_) {
-    return egl_timestamp_client_->GetFrameTimestampInfoIfAvailable(
+    bool result = egl_timestamp_client_->GetFrameTimestampInfoIfAvailable(
         timestamp, interval, flags, frame.frame_id);
+
+    // Workaround null timestamp by setting it to TimeTicks::Now() snapped to
+    // the next vsync interval. See
+    // https://bugs.chromium.org/p/chromium/issues/detail?id=966638 for more
+    // details.
+    if (result && timestamp->is_null()) {
+      *timestamp = base::TimeTicks::Now();
+      *interval = vsync_interval_;
+      *flags = 0;
+      if (!vsync_interval_.is_zero()) {
+        *timestamp =
+            timestamp->SnappedToNextTick(vsync_timebase_, vsync_interval_);
+        *flags = gfx::PresentationFeedback::kVSync;
+      }
+    }
+    return result;
   } else if (frame.timer) {
     if (!frame.timer->IsAvailable())
       return false;
diff --git a/ui/message_center/views/message_popup_collection.cc b/ui/message_center/views/message_popup_collection.cc
index ddc6be9..67b55fd 100644
--- a/ui/message_center/views/message_popup_collection.cc
+++ b/ui/message_center/views/message_popup_collection.cc
@@ -197,6 +197,15 @@
   Update();
 }
 
+MessagePopupView* MessagePopupCollection::GetPopupViewForNotificationID(
+    const std::string& notification_id) {
+  for (const auto& item : popup_items_) {
+    if (item.id == notification_id)
+      return item.popup;
+  }
+  return nullptr;
+}
+
 MessagePopupView* MessagePopupCollection::CreatePopup(
     const Notification& notification) {
   return new MessagePopupView(notification, alignment_delegate_, this);
diff --git a/ui/message_center/views/message_popup_collection.h b/ui/message_center/views/message_popup_collection.h
index 2bab0cb..44656e96 100644
--- a/ui/message_center/views/message_popup_collection.h
+++ b/ui/message_center/views/message_popup_collection.h
@@ -58,6 +58,11 @@
   void AnimationProgressed(const gfx::Animation* animation) override;
   void AnimationCanceled(const gfx::Animation* animation) override;
 
+  // Find the message popup view for the given notification id. Return nullptr
+  // if it does not exist.
+  MessagePopupView* GetPopupViewForNotificationID(
+      const std::string& notification_id);
+
   void set_inverse() { inverse_ = true; }
 
  protected:
diff --git a/ui/ozone/common/linux/BUILD.gn b/ui/ozone/common/linux/BUILD.gn
index 72d8fd8..c808a51 100644
--- a/ui/ozone/common/linux/BUILD.gn
+++ b/ui/ozone/common/linux/BUILD.gn
@@ -17,7 +17,6 @@
     "//base:base",
     "//build/config/linux/libdrm",
     "//ui/gfx:buffer_types",
-    "//ui/gfx:memory_buffer",
   ]
 }
 
diff --git a/ui/ozone/common/linux/drm_util_linux.cc b/ui/ozone/common/linux/drm_util_linux.cc
index f0d1493..3a9ff423 100644
--- a/ui/ozone/common/linux/drm_util_linux.cc
+++ b/ui/ozone/common/linux/drm_util_linux.cc
@@ -7,7 +7,11 @@
 #include <drm_fourcc.h>
 
 #include "base/logging.h"
-#include "ui/gfx/buffer_format_util.h"
+
+#ifndef DRM_FORMAT_INVALID
+// TODO(mcasas): Remove when uprevving //third_party/libdrm.
+#define DRM_FORMAT_INVALID  0
+#endif
 
 namespace ui {
 
@@ -19,6 +23,10 @@
       return DRM_FORMAT_R16;
     case gfx::BufferFormat::RG_88:
       return DRM_FORMAT_GR88;
+    case gfx::BufferFormat::BGR_565:
+      return DRM_FORMAT_RGB565;
+    case gfx::BufferFormat::RGBA_4444:
+      return DRM_FORMAT_INVALID;
     case gfx::BufferFormat::RGBA_8888:
       return DRM_FORMAT_ABGR8888;
     case gfx::BufferFormat::RGBX_8888:
@@ -31,18 +39,16 @@
       return DRM_FORMAT_XRGB2101010;
     case gfx::BufferFormat::RGBX_1010102:
       return DRM_FORMAT_XBGR2101010;
-    case gfx::BufferFormat::BGR_565:
-      return DRM_FORMAT_RGB565;
+    case gfx::BufferFormat::RGBA_F16:
+      return DRM_FORMAT_INVALID;
     case gfx::BufferFormat::UYVY_422:
       return DRM_FORMAT_UYVY;
     case gfx::BufferFormat::YVU_420:
       return DRM_FORMAT_YVU420;
     case gfx::BufferFormat::YUV_420_BIPLANAR:
       return DRM_FORMAT_NV12;
-    default:
-      NOTREACHED() << gfx::BufferFormatToString(format);
-      return 0;
   }
+  return DRM_FORMAT_INVALID;
 }
 
 gfx::BufferFormat GetBufferFormatFromFourCCFormat(int format) {
diff --git a/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc b/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc
index 4c28ee9..094709e 100644
--- a/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc
+++ b/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc
@@ -9,6 +9,7 @@
 #include <utility>
 
 #include "base/files/file_path.h"
+#include "base/strings/stringprintf.h"
 #include "build/build_config.h"
 #include "third_party/khronos/EGL/egl.h"
 #include "ui/gfx/buffer_format_util.h"
@@ -16,6 +17,7 @@
 #include "ui/gl/gl_surface_egl.h"
 #include "ui/ozone/common/egl_util.h"
 #include "ui/ozone/common/gl_ozone_egl.h"
+#include "ui/ozone/common/linux/drm_util_linux.h"
 #include "ui/ozone/platform/drm/common/drm_util.h"
 #include "ui/ozone/platform/drm/gpu/drm_thread_proxy.h"
 #include "ui/ozone/platform/drm/gpu/drm_window_proxy.h"
@@ -92,6 +94,41 @@
   DISALLOW_COPY_AND_ASSIGN(GLOzoneEGLGbm);
 };
 
+std::vector<gfx::BufferFormat> EnumerateSupportedBufferFormatsForTexturing() {
+  std::vector<gfx::BufferFormat> supported_buffer_formats;
+  // We cannot use FileEnumerator here because the sandbox is already closed.
+  constexpr char kRenderNodeFilePattern[] = "/dev/dri/renderD%d";
+  for (int i = 128; /* end on first card# that does not exist */; i++) {
+    base::FilePath dev_path(FILE_PATH_LITERAL(
+        base::StringPrintf(kRenderNodeFilePattern, i).c_str()));
+
+    base::ThreadRestrictions::ScopedAllowIO scoped_allow_io;
+    base::File dev_path_file(dev_path,
+                             base::File::FLAG_OPEN | base::File::FLAG_READ);
+    if (!dev_path_file.IsValid())
+      break;
+
+    gbm_device* device = gbm_create_device(dev_path_file.GetPlatformFile());
+    if (!device) {
+      LOG(ERROR) << "Couldn't create Gbm Device at " << dev_path.MaybeAsASCII();
+      return supported_buffer_formats;
+    }
+
+    for (int i = 0; i <= static_cast<int>(gfx::BufferFormat::LAST); ++i) {
+      const gfx::BufferFormat buffer_format = static_cast<gfx::BufferFormat>(i);
+      if (base::ContainsValue(supported_buffer_formats, buffer_format))
+        continue;
+      if (gbm_device_is_format_supported(
+              device, GetFourCCFormatFromBufferFormat(buffer_format),
+              GBM_BO_USE_TEXTURING)) {
+        supported_buffer_formats.push_back(buffer_format);
+      }
+    }
+    gbm_device_destroy(device);
+  }
+  return supported_buffer_formats;
+}
+
 }  // namespace
 
 GbmSurfaceFactory::GbmSurfaceFactory(DrmThreadProxy* drm_thread_proxy)
@@ -299,4 +336,9 @@
   get_protected_native_pixmap_callback_ = get_protected_native_pixmap_callback;
 }
 
+std::vector<gfx::BufferFormat>
+GbmSurfaceFactory::GetSupportedFormatsForTexturing() const {
+  return EnumerateSupportedBufferFormatsForTexturing();
+}
+
 }  // namespace ui
diff --git a/ui/ozone/platform/drm/gpu/gbm_surface_factory.h b/ui/ozone/platform/drm/gpu/gbm_surface_factory.h
index 74656bd..b2bbb8e4 100644
--- a/ui/ozone/platform/drm/gpu/gbm_surface_factory.h
+++ b/ui/ozone/platform/drm/gpu/gbm_surface_factory.h
@@ -74,6 +74,9 @@
       gfx::BufferFormat format,
       gfx::NativePixmapHandle handle) override;
 
+  std::vector<gfx::BufferFormat> GetSupportedFormatsForTexturing()
+      const override;
+
  private:
   scoped_refptr<gfx::NativePixmap> CreateNativePixmapFromHandleInternal(
       gfx::AcceleratedWidget widget,
diff --git a/ui/ozone/public/surface_factory_ozone.cc b/ui/ozone/public/surface_factory_ozone.cc
index 4c2ee3f8..24809d9 100644
--- a/ui/ozone/public/surface_factory_ozone.cc
+++ b/ui/ozone/public/surface_factory_ozone.cc
@@ -100,4 +100,9 @@
     const GetProtectedNativePixmapCallback&
         get_protected_native_pixmap_callback) {}
 
+std::vector<gfx::BufferFormat>
+SurfaceFactoryOzone::GetSupportedFormatsForTexturing() const {
+  return std::vector<gfx::BufferFormat>();
+}
+
 }  // namespace ui
diff --git a/ui/ozone/public/surface_factory_ozone.h b/ui/ozone/public/surface_factory_ozone.h
index c6bd481..ba04a36 100644
--- a/ui/ozone/public/surface_factory_ozone.h
+++ b/ui/ozone/public/surface_factory_ozone.h
@@ -160,6 +160,13 @@
       const GetProtectedNativePixmapCallback&
           get_protected_native_pixmap_callback);
 
+  // Enumerates the BufferFormats that the platform can allocate (and use for
+  // texturing) via CreateNativePixmap(), or returns empty if those could not be
+  // retrieved or the platform doesn't know in advance.
+  // Enumeration should not be assumed to take a trivial amount of time.
+  virtual std::vector<gfx::BufferFormat> GetSupportedFormatsForTexturing()
+      const;
+
  protected:
   SurfaceFactoryOzone();
   virtual ~SurfaceFactoryOzone();
diff --git a/ui/shell_dialogs/BUILD.gn b/ui/shell_dialogs/BUILD.gn
index 935723a2..429d75c5 100644
--- a/ui/shell_dialogs/BUILD.gn
+++ b/ui/shell_dialogs/BUILD.gn
@@ -75,6 +75,7 @@
       "Foundation.framework",
       "AppKit.framework",
     ]
+    deps += [ "//components/remote_cocoa/browser" ]
   }
 
   if (is_fuchsia) {
diff --git a/ui/shell_dialogs/DEPS b/ui/shell_dialogs/DEPS
index 41751b8..eda7619 100644
--- a/ui/shell_dialogs/DEPS
+++ b/ui/shell_dialogs/DEPS
@@ -1,5 +1,6 @@
 include_rules = [
   "+jni",
+  "+components/remote_cocoa/browser/window.h",
   "+ui/android/window_android.h",
   "+ui/aura",
   "+ui/base",
diff --git a/ui/shell_dialogs/select_file_dialog_mac.mm b/ui/shell_dialogs/select_file_dialog_mac.mm
index 0d8913e..77d05b4 100644
--- a/ui/shell_dialogs/select_file_dialog_mac.mm
+++ b/ui/shell_dialogs/select_file_dialog_mac.mm
@@ -18,8 +18,8 @@
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread_restrictions.h"
+#include "components/remote_cocoa/browser/window.h"
 #import "ui/base/cocoa/controls/textfield_utils.h"
-#include "ui/base/cocoa/remote_views_window.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 #include "ui/shell_dialogs/select_file_policy.h"
 #include "ui/strings/grit/ui_strings.h"
@@ -189,7 +189,7 @@
   // Cocoa should be wrapped in a mojo interface in order to allow instantiating
   // across processes. As a temporary solution, raise the remote windows'
   // transparent in-process window to the front.
-  if (ui::IsWindowUsingRemoteViews(owning_window)) {
+  if (remote_cocoa::IsWindowRemote(owning_window)) {
     [owning_window makeKeyAndOrderFront:nil];
     [owning_window setLevel:NSModalPanelWindowLevel];
   }
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn
index 5402768b..ab6b106 100644
--- a/ui/views/BUILD.gn
+++ b/ui/views/BUILD.gn
@@ -783,6 +783,7 @@
     deps += [
       "//components/crash/core/common",
       "//components/remote_cocoa/app_shim",
+      "//components/remote_cocoa/browser",
       "//ui/accelerated_widget_mac",
       "//ui/events:dom_keycode_converter",
     ]
diff --git a/ui/views/animation/square_ink_drop_ripple_unittest.cc b/ui/views/animation/square_ink_drop_ripple_unittest.cc
index 5711207e..8dfd33ea 100644
--- a/ui/views/animation/square_ink_drop_ripple_unittest.cc
+++ b/ui/views/animation/square_ink_drop_ripple_unittest.cc
@@ -159,20 +159,20 @@
        gfx::Point(0, 0), gfx::Point(0, -kHalfTransformedSize),
        gfx::Point(0, kHalfTransformedSize)}};
 
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
-    PaintedShape shape = test_cases[i].shape;
-    SCOPED_TRACE(testing::Message() << "i=" << i << " shape=" << shape);
+  for (const auto& test_case : test_cases) {
+    PaintedShape shape = test_case.shape;
+    SCOPED_TRACE(testing::Message() << " shape=" << shape);
     gfx::Transform transform = transforms_[shape];
 
-    EXPECT_EQ(test_cases[i].center_point,
+    EXPECT_EQ(test_case.center_point,
               TransformPoint(transform, kDrawnCenterPoint));
-    EXPECT_EQ(test_cases[i].mid_left_point,
+    EXPECT_EQ(test_case.mid_left_point,
               TransformPoint(transform, kDrawnMidLeftPoint));
-    EXPECT_EQ(test_cases[i].mid_right_point,
+    EXPECT_EQ(test_case.mid_right_point,
               TransformPoint(transform, kDrawnMidRightPoint));
-    EXPECT_EQ(test_cases[i].top_mid_point,
+    EXPECT_EQ(test_case.top_mid_point,
               TransformPoint(transform, kDrawnTopMidPoint));
-    EXPECT_EQ(test_cases[i].bottom_mid_point,
+    EXPECT_EQ(test_case.bottom_mid_point,
               TransformPoint(transform, kDrawnBottomMidPoint));
   }
 }
@@ -222,20 +222,20 @@
        gfx::Point(x_offset, 0), gfx::Point(0, -kHalfTransformedSize),
        gfx::Point(0, kHalfTransformedSize)}};
 
-  for (size_t i = 0; i < base::size(test_cases); ++i) {
-    PaintedShape shape = test_cases[i].shape;
-    SCOPED_TRACE(testing::Message() << "i=" << i << " shape=" << shape);
+  for (const auto& test_case : test_cases) {
+    PaintedShape shape = test_case.shape;
+    SCOPED_TRACE(testing::Message() << " shape=" << shape);
     gfx::Transform transform = transforms_[shape];
 
-    EXPECT_EQ(test_cases[i].center_point,
+    EXPECT_EQ(test_case.center_point,
               TransformPoint(transform, kDrawnCenterPoint));
-    EXPECT_EQ(test_cases[i].mid_left_point,
+    EXPECT_EQ(test_case.mid_left_point,
               TransformPoint(transform, kDrawnMidLeftPoint));
-    EXPECT_EQ(test_cases[i].mid_right_point,
+    EXPECT_EQ(test_case.mid_right_point,
               TransformPoint(transform, kDrawnMidRightPoint));
-    EXPECT_EQ(test_cases[i].top_mid_point,
+    EXPECT_EQ(test_case.top_mid_point,
               TransformPoint(transform, kDrawnTopMidPoint));
-    EXPECT_EQ(test_cases[i].bottom_mid_point,
+    EXPECT_EQ(test_case.bottom_mid_point,
               TransformPoint(transform, kDrawnBottomMidPoint));
   }
 }
diff --git a/ui/views/cocoa/bridged_native_widget_host_impl.h b/ui/views/cocoa/bridged_native_widget_host_impl.h
index c17a8bb..75f3dd1 100644
--- a/ui/views/cocoa/bridged_native_widget_host_impl.h
+++ b/ui/views/cocoa/bridged_native_widget_host_impl.h
@@ -11,13 +11,13 @@
 #include "base/mac/scoped_nsobject.h"
 #include "base/macros.h"
 #include "components/remote_cocoa/app_shim/bridged_native_widget_host_helper.h"
+#include "components/remote_cocoa/app_shim/ns_view_ids.h"
 #include "components/remote_cocoa/common/bridged_native_widget.mojom.h"
 #include "components/remote_cocoa/common/bridged_native_widget_host.mojom.h"
 #include "mojo/public/cpp/bindings/associated_binding.h"
 #include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
 #include "ui/accelerated_widget_mac/display_link_mac.h"
 #include "ui/base/cocoa/accessibility_focus_overrider.h"
-#include "ui/base/cocoa/ns_view_ids.h"
 #include "ui/base/ime/input_method_delegate.h"
 #include "ui/compositor/layer_owner.h"
 #include "ui/views/cocoa/bridge_factory_host.h"
@@ -416,7 +416,7 @@
   base::scoped_nsobject<NativeWidgetMacNSWindow> local_window_;
 
   // Id mapping for |local_window_|'s content NSView.
-  std::unique_ptr<ui::ScopedNSViewIdMapping> local_view_id_mapping_;
+  std::unique_ptr<remote_cocoa::ScopedNSViewIdMapping> local_view_id_mapping_;
 
   std::unique_ptr<TooltipManager> tooltip_manager_;
   std::unique_ptr<ui::InputMethod> input_method_;
diff --git a/ui/views/cocoa/bridged_native_widget_host_impl.mm b/ui/views/cocoa/bridged_native_widget_host_impl.mm
index 69c4f9d..be87bb2 100644
--- a/ui/views/cocoa/bridged_native_widget_host_impl.mm
+++ b/ui/views/cocoa/bridged_native_widget_host_impl.mm
@@ -11,6 +11,7 @@
 #include "components/remote_cocoa/app_shim/bridged_native_widget_impl.h"
 #include "components/remote_cocoa/app_shim/mouse_capture.h"
 #include "components/remote_cocoa/app_shim/native_widget_mac_nswindow.h"
+#include "components/remote_cocoa/browser/ns_view_ids.h"
 #include "mojo/public/cpp/bindings/strong_associated_binding.h"
 #include "ui/accelerated_widget_mac/window_resize_helper_mac.h"
 #include "ui/base/cocoa/animation_utils.h"
@@ -293,7 +294,7 @@
 BridgedNativeWidgetHostImpl::BridgedNativeWidgetHostImpl(NativeWidgetMac* owner)
     : widget_id_(++g_last_bridged_native_widget_id),
       native_widget_mac_(owner),
-      root_view_id_(ui::NSViewIds::GetNewId()),
+      root_view_id_(remote_cocoa::GetNewNSViewId()),
       accessibility_focus_overrider_(this),
       text_input_host_(new TextInputHost(this)),
       host_mojo_binding_(this) {
@@ -387,8 +388,9 @@
         local_window_create_params.get());
     [local_window_ setBridgedNativeWidgetId:widget_id_];
     [local_window_ setAlphaValue:0.0];
-    local_view_id_mapping_ = std::make_unique<ui::ScopedNSViewIdMapping>(
-        root_view_id_, [local_window_ contentView]);
+    local_view_id_mapping_ =
+        std::make_unique<remote_cocoa::ScopedNSViewIdMapping>(
+            root_view_id_, [local_window_ contentView]);
   }
 
   // Initialize |bridge_ptr_| to point to a bridge created by |factory|.
diff --git a/ui/views/controls/button/image_button.cc b/ui/views/controls/button/image_button.cc
index 38be79d4..ea134d4e 100644
--- a/ui/views/controls/button/image_button.cc
+++ b/ui/views/controls/button/image_button.cc
@@ -242,11 +242,8 @@
   if (toggled == toggled_)
     return;
 
-  for (int i = 0; i < STATE_COUNT; ++i) {
-    gfx::ImageSkia temp = images_[i];
-    images_[i] = alternate_images_[i];
-    alternate_images_[i] = temp;
-  }
+  for (int i = 0; i < STATE_COUNT; ++i)
+    std::swap(images_[i], alternate_images_[i]);
   toggled_ = toggled;
   SchedulePaint();
 
diff --git a/ui/views/controls/button/radio_button.cc b/ui/views/controls/button/radio_button.cc
index 5b6a23c..e7189a592 100644
--- a/ui/views/controls/button/radio_button.cc
+++ b/ui/views/controls/button/radio_button.cc
@@ -38,16 +38,12 @@
 View* RadioButton::GetSelectedViewForGroup(int group) {
   Views views;
   GetViewsInGroupFromParent(group, &views);
-  if (views.empty())
-    return nullptr;
-
-  for (Views::const_iterator i(views.begin()); i != views.end(); ++i) {
-    // REVIEW: why don't we check the runtime type like is done above?
-    RadioButton* radio_button = static_cast<RadioButton*>(*i);
-    if (radio_button->GetChecked())
-      return radio_button;
-  }
-  return nullptr;
+  const auto i =
+      std::find_if(views.cbegin(), views.cend(), [](const auto* view) {
+        // Why don't we check the runtime type like is done in SetChecked()?
+        return static_cast<const RadioButton*>(view)->GetChecked();
+      });
+  return (i == views.cend()) ? nullptr : *i;
 }
 
 bool RadioButton::IsGroupFocusTraversable() const {
@@ -66,11 +62,9 @@
   // Take focus only if another radio button in the group has focus.
   Views views;
   GetViewsInGroupFromParent(GetGroup(), &views);
-  if (std::find_if(views.begin(), views.end(), [](View* v) -> bool {
-        return v->HasFocus();
-      }) != views.end()) {
+  if (std::any_of(views.begin(), views.end(),
+                  [](View* v) { return v->HasFocus(); }))
     RequestFocus();
-  }
 }
 
 void RadioButton::NotifyClick(const ui::Event& event) {
@@ -116,9 +110,8 @@
 }
 
 void RadioButton::GetViewsInGroupFromParent(int group, Views* views) {
-  if (!parent())
-    return;
-  parent()->GetViewsInGroup(group, views);
+  if (parent())
+    parent()->GetViewsInGroup(group, views);
 }
 
 }  // namespace views
diff --git a/ui/views/controls/editable_combobox/editable_combobox_unittest.cc b/ui/views/controls/editable_combobox/editable_combobox_unittest.cc
index ccecb63..1114ea17 100644
--- a/ui/views/controls/editable_combobox/editable_combobox_unittest.cc
+++ b/ui/views/controls/editable_combobox/editable_combobox_unittest.cc
@@ -120,9 +120,8 @@
                                                 const bool filter_on_edit,
                                                 const bool show_on_empty) {
   std::vector<base::string16> items;
-  for (int i = 0; i < item_count; ++i) {
+  for (int i = 0; i < item_count; ++i)
     items.push_back(ASCIIToUTF16(base::StringPrintf("item[%i]", i)));
-  }
   InitEditableCombobox(items, filter_on_edit, show_on_empty);
 }
 
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc
index 79f32b9..3ae7da5 100644
--- a/ui/views/controls/menu/menu_controller.cc
+++ b/ui/views/controls/menu/menu_controller.cc
@@ -931,7 +931,7 @@
     // removed while a menu is up.
     if (details.child == hot_button_) {
       hot_button_ = nullptr;
-      for (auto&& nested_state : menu_stack_) {
+      for (auto& nested_state : menu_stack_) {
         State& state = nested_state.first;
         if (details.child == state.hot_button)
           state.hot_button = nullptr;
@@ -1736,7 +1736,7 @@
 }
 
 void MenuController::CloseAllNestedMenus() {
-  for (auto&& nested_menu : menu_stack_) {
+  for (auto& nested_menu : menu_stack_) {
     State& state = nested_menu.first;
     MenuItemView* last_item = state.item;
     for (MenuItemView* item = last_item; item;
@@ -1942,9 +1942,8 @@
   // Open all the submenus preceeding the last menu item (last menu item is
   // handled next).
   if (new_path.size() > 1) {
-    for (auto i = new_path.begin(); i != new_path.end() - 1; ++i) {
+    for (auto i = new_path.begin(); i != new_path.end() - 1; ++i)
       OpenMenu(*i);
-    }
   }
 
   if (state_.submenu_open) {
@@ -2088,18 +2087,10 @@
   BuildMenuItemPath(old_item, old_path);
   BuildMenuItemPath(new_item, new_path);
 
-  size_t common_size = std::min(old_path->size(), new_path->size());
-
-  // Find the first difference between the two paths, when the loop
-  // returns, diff_i is the first index where the two paths differ.
-  for (size_t i = 0; i < common_size; ++i) {
-    if ((*old_path)[i] != (*new_path)[i]) {
-      *first_diff_at = i;
-      return;
-    }
-  }
-
-  *first_diff_at = common_size;
+  *first_diff_at = std::distance(
+      old_path->cbegin(), std::mismatch(old_path->cbegin(), old_path->cend(),
+                                        new_path->cbegin(), new_path->cend())
+                              .first);
 }
 
 void MenuController::BuildMenuItemPath(MenuItemView* item,
@@ -2506,10 +2497,8 @@
     return;
 
   const int set_size = ordering.size();
-  for (int i = 0; i < set_size; ++i) {
-    const int set_pos = i + 1;  // 1-indexed
-    ordering[i]->GetViewAccessibility().OverridePosInSet(set_pos, set_size);
-  }
+  for (int i = 0; i < set_size; ++i)
+    ordering[i]->GetViewAccessibility().OverridePosInSet(i + 1, set_size);
 }
 
 void MenuController::MoveSelectionToFirstOrLastItem(
diff --git a/ui/views/controls/menu/menu_controller_unittest.cc b/ui/views/controls/menu/menu_controller_unittest.cc
index 24039c4..57031c8 100644
--- a/ui/views/controls/menu/menu_controller_unittest.cc
+++ b/ui/views/controls/menu/menu_controller_unittest.cc
@@ -695,7 +695,7 @@
     menu_item()->SetBounds(0, 0, 200, 300);
     MenuItemView* item_view =
         menu_item()->AppendMenuItemWithLabel(5, base::ASCIIToUTF16("Five"));
-    for (int i = 0; i < 3; ++i) {
+    for (size_t i = 0; i < 3; ++i) {
       LabelButton* button =
           new LabelButton(nullptr, base::ASCIIToUTF16("Label"));
       // This is an in-menu button. Hence it must be always focusable.
diff --git a/ui/views/controls/menu/native_menu_win.cc b/ui/views/controls/menu/native_menu_win.cc
index ed0ba30..3e0ce9c 100644
--- a/ui/views/controls/menu/native_menu_win.cc
+++ b/ui/views/controls/menu/native_menu_win.cc
@@ -68,9 +68,9 @@
 
   owner_draw_ = model_->HasIcons() || owner_draw_;
   first_item_index_ = delegate ? delegate->GetInsertionIndex(menu_) : 0;
-  for (int menu_index = first_item_index_;
-        menu_index < first_item_index_ + model_->GetItemCount(); ++menu_index) {
-    int model_index = menu_index - first_item_index_;
+  for (int model_index = 0; model_index < model_->GetItemCount();
+       ++model_index) {
+    int menu_index = model_index + first_item_index_;
     if (model_->GetTypeAt(model_index) == ui::MenuModel::TYPE_SEPARATOR)
       AddSeparatorItemAt(menu_index, model_index);
     else
@@ -81,7 +81,7 @@
 void NativeMenuWin::UpdateStates() {
   // A depth-first walk of the menu items, updating states.
   int model_index = 0;
-  for (auto it = items_.begin(); it != items_.end(); ++it, ++model_index) {
+  for (const auto& item : items_) {
     int menu_index = model_index + first_item_index_;
     SetMenuItemState(menu_index, model_->IsEnabledAt(model_index),
                      model_->IsItemCheckedAt(model_index), false);
@@ -90,9 +90,10 @@
       SetMenuItemLabel(menu_index, model_index,
                        model_->GetLabelAt(model_index));
     }
-    NativeMenuWin* submenu = (*it)->submenu.get();
+    NativeMenuWin* submenu = item->submenu.get();
     if (submenu)
       submenu->UpdateStates();
+    ++model_index;
   }
 }
 
diff --git a/ui/views/controls/table/table_view.cc b/ui/views/controls/table/table_view.cc
index 04636b0..84703890 100644
--- a/ui/views/controls/table/table_view.cc
+++ b/ui/views/controls/table/table_view.cc
@@ -62,8 +62,8 @@
     GroupRange range;
     grouper->GetGroupRange(model_index, &range);
     DCHECK_GT(range.length, 0);
-    for (int range_counter = 0; range_counter < range.length; range_counter++)
-      (*model_index_to_range_start)[range_counter + model_index] = model_index;
+    for (int i = model_index; i < model_index + range.length; ++i)
+      (*model_index_to_range_start)[i] = model_index;
     model_index += range.length;
   }
 }
@@ -220,16 +220,13 @@
     visible_column.column = FindColumnByID(id);
     visible_columns_.push_back(visible_column);
   } else {
-    for (size_t i = 0; i < visible_columns_.size(); ++i) {
-      if (visible_columns_[i].column.id == id) {
-        visible_columns_.erase(visible_columns_.begin() + i);
-        if (active_visible_column_index_ >=
-            static_cast<int>(visible_columns_.size())) {
-          SetActiveVisibleColumnIndex(
-              static_cast<int>(visible_columns_.size()) - 1);
-        }
-        break;
-      }
+    const auto i = std::find_if(
+        visible_columns_.begin(), visible_columns_.end(),
+        [id](const auto& column) { return column.column.id == id; });
+    if (i != visible_columns_.end()) {
+      visible_columns_.erase(i);
+      if (active_visible_column_index_ >= int{visible_columns_.size()})
+        SetActiveVisibleColumnIndex(int{visible_columns_.size()} - 1);
     }
   }
   UpdateVisibleColumnSizes();
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc
index f515839c..6e7b2d8d 100644
--- a/ui/views/controls/textfield/textfield.cc
+++ b/ui/views/controls/textfield/textfield.cc
@@ -726,9 +726,9 @@
       ui::GetTextEditKeyBindingsDelegate();
   std::vector<ui::TextEditCommandAuraLinux> commands;
   if (!handled && delegate && delegate->MatchEvent(event, &commands)) {
-    for (size_t i = 0; i < commands.size(); ++i) {
-      if (IsTextEditCommandEnabled(commands[i].command())) {
-        ExecuteTextEditCommand(commands[i].command());
+    for (const auto& command : commands) {
+      if (IsTextEditCommandEnabled(command.command())) {
+        ExecuteTextEditCommand(command.command());
         handled = true;
       }
     }
@@ -896,9 +896,11 @@
       ui::GetTextEditKeyBindingsDelegate();
   std::vector<ui::TextEditCommandAuraLinux> commands;
   if (delegate && delegate->MatchEvent(event, &commands)) {
-    for (size_t i = 0; i < commands.size(); ++i)
-      if (IsTextEditCommandEnabled(commands[i].command()))
-        return true;
+    const auto is_enabled = [this](const auto& command) {
+      return IsTextEditCommandEnabled(command.command());
+    };
+    if (std::any_of(commands.cbegin(), commands.cend(), is_enabled))
+      return true;
   }
 #endif
 
@@ -1369,7 +1371,7 @@
     return text_services_context_menu_->IsCommandIdEnabled(command_id);
   }
 
-  return Textfield::IsTextEditCommandEnabled(
+  return IsTextEditCommandEnabled(
       GetTextEditCommandFromMenuCommand(command_id, HasSelection()));
 }
 
@@ -1838,7 +1840,7 @@
 
   // We only execute the commands enabled in Textfield::IsTextEditCommandEnabled
   // below. Hence don't do a virtual IsTextEditCommandEnabled call.
-  if (!Textfield::IsTextEditCommandEnabled(command))
+  if (!IsTextEditCommandEnabled(command))
     return;
 
   bool text_changed = false;
diff --git a/ui/views/controls/textfield/textfield_unittest.cc b/ui/views/controls/textfield/textfield_unittest.cc
index 997bcdf..7469353a 100644
--- a/ui/views/controls/textfield/textfield_unittest.cc
+++ b/ui/views/controls/textfield/textfield_unittest.cc
@@ -1168,10 +1168,10 @@
 
   // Test the delete and backspace keys.
   textfield_->SelectRange(gfx::Range(5));
-  for (int i = 0; i < 3; i++)
+  for (size_t i = 0; i < 3; i++)
     SendKeyEvent(ui::VKEY_BACK);
   EXPECT_STR_EQ("abfghij", textfield_->text());
-  for (int i = 0; i < 3; i++)
+  for (size_t i = 0; i < 3; i++)
     SendKeyEvent(ui::VKEY_DELETE);
   EXPECT_STR_EQ("abij", textfield_->text());
 
@@ -2584,7 +2584,7 @@
   size_t cursor_pos_expected[] = {0, 1, 1, 2, 4, 3, 3, 2};
 
   int index = 0;
-  for (int i = 0; i < static_cast<int>(cursor_bounds.size() - 1); ++i) {
+  for (size_t i = 0; i < cursor_bounds.size() - 1; ++i) {
     int half_width = (cursor_bounds[i + 1].x() - cursor_bounds[i].x()) / 2;
     MouseClick(cursor_bounds[i], half_width / 2);
     EXPECT_EQ(cursor_pos_expected[index++], textfield_->GetCursorPosition());
@@ -2593,7 +2593,7 @@
     // for the test to run if using sleep().
     NonClientMouseClick();
 
-    MouseClick(cursor_bounds[i + 1], - (half_width / 2));
+    MouseClick(cursor_bounds[i + 1], -(half_width / 2));
     EXPECT_EQ(cursor_pos_expected[index++], textfield_->GetCursorPosition());
 
     NonClientMouseClick();
@@ -2674,7 +2674,7 @@
   InitTextfield();
 
   base::string16 str;
-  for (int i = 0; i < 500; ++i)
+  for (size_t i = 0; i < 500; ++i)
     SendKeyEvent('a');
   SendKeyEvent(kHebrewLetterSamekh);
   EXPECT_TRUE(GetDisplayRect().Contains(GetCursorBounds()));
@@ -2687,7 +2687,7 @@
   SendKeyEvent(ui::VKEY_A, false, true);
   SendKeyEvent(ui::VKEY_DELETE);
 
-  for (int i = 0; i < 500; ++i)
+  for (size_t i = 0; i < 500; ++i)
     SendKeyEvent(kHebrewLetterSamekh);
   SendKeyEvent('a');
   EXPECT_TRUE(GetDisplayRect().Contains(GetCursorBounds()));
@@ -2703,7 +2703,7 @@
   InitTextfield();
 
   base::string16 str;
-  for (int i = 0; i < 500; ++i)
+  for (size_t i = 0; i < 500; ++i)
     SendKeyEvent('a');
   SendKeyEvent(kHebrewLetterSamekh);
   EXPECT_TRUE(GetDisplayRect().Contains(GetCursorBounds()));
@@ -2715,7 +2715,7 @@
   SendKeyEvent(ui::VKEY_A, false, true);
   SendKeyEvent(ui::VKEY_DELETE);
 
-  for (int i = 0; i < 500; ++i)
+  for (size_t i = 0; i < 500; ++i)
     SendKeyEvent(kHebrewLetterSamekh);
   SendKeyEvent('a');
   EXPECT_TRUE(GetDisplayRect().Contains(GetCursorBounds()));
diff --git a/ui/views/examples/radio_button_example.cc b/ui/views/examples/radio_button_example.cc
index 4923f96..d1e25be 100644
--- a/ui/views/examples/radio_button_example.cc
+++ b/ui/views/examples/radio_button_example.cc
@@ -7,7 +7,7 @@
 #include <stddef.h>
 
 #include "base/stl_util.h"
-#include "base/strings/stringprintf.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "ui/views/controls/button/label_button.h"
 #include "ui/views/controls/button/radio_button.h"
@@ -30,30 +30,25 @@
 RadioButtonExample::~RadioButtonExample() = default;
 
 void RadioButtonExample::CreateExampleView(View* container) {
-  select_ = new LabelButton(this, base::ASCIIToUTF16("Select"));
-  status_ = new LabelButton(this, base::ASCIIToUTF16("Show Status"));
-
-  int group = 1;
-  for (size_t i = 0; i < base::size(radio_buttons_); ++i) {
-    radio_buttons_[i] = new RadioButton(
-        base::UTF8ToUTF16(base::StringPrintf(
-            "Radio %d in group %d", static_cast<int>(i) + 1, group)),
-        group);
-  }
-
   GridLayout* layout = container->SetLayoutManager(
       std::make_unique<views::GridLayout>(container));
-
   ColumnSet* column_set = layout->AddColumnSet(0);
   column_set->AddColumn(GridLayout::FILL, GridLayout::FILL,
                         1.0f, GridLayout::USE_PREF, 0, 0);
-  for (size_t i = 0; i < base::size(radio_buttons_); ++i) {
+
+  for (size_t i = 0; i < 3; ++i) {
     layout->StartRow(0, 0);
-    layout->AddView(radio_buttons_[i]);
+    radio_buttons_.push_back(new RadioButton(
+        base::ASCIIToUTF16("Radio ") + base::NumberToString16(i), 1));
+    layout->AddView(radio_buttons_.back());
   }
+
   layout->StartRow(0, 0);
+  select_ = new LabelButton(this, base::ASCIIToUTF16("Select"));
   layout->AddView(select_);
+
   layout->StartRow(0, 0);
+  status_ = new LabelButton(this, base::ASCIIToUTF16("Show Status"));
   layout->AddView(status_);
 }
 
diff --git a/ui/views/examples/radio_button_example.h b/ui/views/examples/radio_button_example.h
index 0cb2edf0..889934e 100644
--- a/ui/views/examples/radio_button_example.h
+++ b/ui/views/examples/radio_button_example.h
@@ -6,6 +6,7 @@
 #define UI_VIEWS_EXAMPLES_RADIO_BUTTON_EXAMPLE_H_
 
 #include <string>
+#include <vector>
 
 #include "base/macros.h"
 #include "ui/views/controls/button/button.h"
@@ -32,7 +33,7 @@
   void ButtonPressed(Button* sender, const ui::Event& event) override;
 
   // Group of 3 radio buttons.
-  RadioButton* radio_buttons_[3];
+  std::vector<RadioButton*> radio_buttons_;
 
   // Control button to select radio buttons, and show the status of buttons.
   LabelButton* select_;
diff --git a/ui/views/examples/scroll_view_example.cc b/ui/views/examples/scroll_view_example.cc
index fa12476..a5d6c18 100644
--- a/ui/views/examples/scroll_view_example.cc
+++ b/ui/views/examples/scroll_view_example.cc
@@ -97,7 +97,7 @@
 
   // Add control buttons.
   column_set = layout->AddColumnSet(1);
-  for (int i = 0; i < 5; i++) {
+  for (size_t i = 0; i < 5; i++) {
     column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
                           GridLayout::USE_PREF, 0, 0);
   }
diff --git a/ui/views/examples/tabbed_pane_example.cc b/ui/views/examples/tabbed_pane_example.cc
index ca45c60..c4b0f6c 100644
--- a/ui/views/examples/tabbed_pane_example.cc
+++ b/ui/views/examples/tabbed_pane_example.cc
@@ -44,7 +44,7 @@
   // Add control buttons horizontally.
   const int button_column = 1;
   column_set = layout->AddColumnSet(button_column);
-  for (int i = 0; i < 3; i++) {
+  for (size_t i = 0; i < 3; i++) {
     column_set->AddColumn(GridLayout::FILL, GridLayout::FILL,
                           1.0f, GridLayout::USE_PREF, 0, 0);
   }
diff --git a/ui/views/examples/tree_view_example.cc b/ui/views/examples/tree_view_example.cc
index 4df1b91d..38cce7c 100644
--- a/ui/views/examples/tree_view_example.cc
+++ b/ui/views/examples/tree_view_example.cc
@@ -98,7 +98,7 @@
   // Add control buttons horizontally.
   const int button_column = 1;
   column_set = layout->AddColumnSet(button_column);
-  for (int i = 0; i < 3; i++) {
+  for (size_t i = 0; i < 3; i++) {
     column_set->AddColumn(GridLayout::FILL, GridLayout::FILL,
                           1.0f, GridLayout::USE_PREF, 0, 0);
   }
diff --git a/ui/views/focus/focus_manager.cc b/ui/views/focus/focus_manager.cc
index b887f19..b530ffb 100644
--- a/ui/views/focus/focus_manager.cc
+++ b/ui/views/focus/focus_manager.cc
@@ -160,9 +160,9 @@
 
   // Count the number of panes and set the default index if no pane
   // is initially focused.
-  int count = static_cast<int>(panes.size());
-  if (count == 0)
+  if (panes.empty())
     return false;
+  int count = int{panes.size()};
 
   // Initialize |index| to an appropriate starting index if nothing is
   // focused initially.
@@ -171,12 +171,12 @@
   // Check to see if a pane already has focus and update the index accordingly.
   const views::View* focused_view = GetFocusedView();
   if (focused_view) {
-    for (int i = 0; i < count; i++) {
-      if (panes[i] && panes[i]->Contains(focused_view)) {
-        index = i;
-        break;
-      }
-    }
+    const auto i = std::find_if(panes.cbegin(), panes.cend(),
+                                [focused_view](const auto* pane) {
+                                  return pane && pane->Contains(focused_view);
+                                });
+    if (i != panes.cend())
+      index = i - panes.cbegin();
   }
 
   // Rotate focus.
diff --git a/ui/views/layout/flex_layout_unittest.cc b/ui/views/layout/flex_layout_unittest.cc
index b175fe83..f32ba756 100644
--- a/ui/views/layout/flex_layout_unittest.cc
+++ b/ui/views/layout/flex_layout_unittest.cc
@@ -1745,7 +1745,7 @@
     FlexLayoutTest::SetUp();
     DCHECK(child_views_.empty());
 
-    for (int i = 0; i < kNumChildren; ++i) {
+    for (size_t i = 0; i < kNumChildren; ++i) {
       View* const child = AddChild(kChildSizes[i]);
       child->SetProperty(kMarginsKey, new gfx::Insets(kChildMargins[i]));
       child_views_.push_back(child);
@@ -1760,7 +1760,7 @@
   void TearDown() override { child_views_.clear(); }
 
  protected:
-  static constexpr int kNumChildren = 3;
+  static constexpr size_t kNumChildren = 3;
   static const gfx::Size kHostSize;
   static const gfx::Size kChildSizes[kNumChildren];
   static const gfx::Insets kChildMargins[kNumChildren];
@@ -1784,7 +1784,7 @@
 
   // Expect child views to respect their leading margin and to occupy all
   // available space (other than margins), with a minimum size of zero.
-  for (int i = 0; i < kNumChildren; ++i) {
+  for (size_t i = 0; i < kNumChildren; ++i) {
     EXPECT_EQ(kChildMargins[i].top(), child_views_[i]->origin().y());
     const int expected_height =
         std::max(0, kHostSize.height() - kChildMargins[i].height());
@@ -1797,7 +1797,7 @@
   host_->Layout();
 
   // These should all justify to the leading edge and keep their original size.
-  for (int i = 0; i < kNumChildren; ++i) {
+  for (size_t i = 0; i < kNumChildren; ++i) {
     EXPECT_EQ(kChildMargins[i].top(), child_views_[i]->origin().y());
     EXPECT_EQ(kChildSizes[i].height(), child_views_[i]->size().height());
   }
@@ -1827,9 +1827,8 @@
   EXPECT_EQ(expected, child_views_[2]->origin().y());
 
   // Expect child views to retain their preferred sizes.
-  for (int i = 0; i < kNumChildren; ++i) {
+  for (size_t i = 0; i < kNumChildren; ++i)
     EXPECT_EQ(kChildSizes[i].height(), child_views_[i]->size().height());
-  }
 }
 
 TEST_F(FlexLayoutCrossAxisFitTest, Layout_CrossEnd) {
@@ -1837,7 +1836,7 @@
   host_->Layout();
 
   // These should all justify to the trailing edge and keep their original size.
-  for (int i = 0; i < kNumChildren; ++i) {
+  for (size_t i = 0; i < kNumChildren; ++i) {
     EXPECT_EQ(kHostSize.height() - kChildMargins[i].bottom(),
               child_views_[i]->bounds().bottom());
     EXPECT_EQ(kChildSizes[i].height(), child_views_[i]->size().height());
diff --git a/ui/views/layout/grid_layout.cc b/ui/views/layout/grid_layout.cc
index ad5cf59..c5565437 100644
--- a/ui/views/layout/grid_layout.cc
+++ b/ui/views/layout/grid_layout.cc
@@ -5,6 +5,7 @@
 #include "ui/views/layout/grid_layout.h"
 
 #include <cmath>
+#include <numeric>
 
 #include "base/memory/ptr_util.h"
 #include "base/stl_util.h"
@@ -101,13 +102,12 @@
   static int TotalSize(int start,
                        int length,
                        std::vector<std::unique_ptr<T>>* elements) {
-    DCHECK(start >= 0 && length > 0 &&
-           start + length <= static_cast<int>(elements->size()));
-    int size = 0;
-    for (int i = start, max = start + length; i < max; ++i) {
-      size += (*elements)[i]->Size();
-    }
-    return size;
+    DCHECK_GE(start, 0);
+    DCHECK_GT(length, 0);
+    DCHECK_LE(size_t{start + length}, elements->size());
+    return std::accumulate(
+        elements->cbegin() + start, elements->cbegin() + start + length, 0,
+        [](int size, const auto& elem) { return size + elem->Size(); });
   }
 
   explicit LayoutElement(float resize_percent)
@@ -425,7 +425,8 @@
   DCHECK(first >= 0 && first < num_columns());
   for (int last = first, next = va_arg(marker, int); next != -1;
        next = va_arg(marker, int)) {
-    DCHECK(next >= 0 && next < num_columns());
+    DCHECK_GE(next, 0);
+    DCHECK_LT(next, num_columns());
     columns_[last]->same_size_column_ = next;
     last = next;
   }
@@ -531,11 +532,8 @@
 }
 
 void ColumnSet::UpdateRemainingWidth(ViewState* view_state) {
-  for (int i = view_state->start_col,
-       max_col = view_state->start_col + view_state->col_span;
-       i < max_col; ++i) {
-    view_state->remaining_width -= columns_[i]->Size();
-  }
+  view_state->remaining_width -= LayoutElement::TotalSize(
+      view_state->start_col, view_state->col_span, &columns_);
 }
 
 void ColumnSet::DistributeRemainingWidth(ViewState* view_state) {
@@ -763,13 +761,13 @@
 }
 
 bool ColumnSet::CanUseMinimum(const ViewState& view_state) const {
-  for (int i = 0; i < view_state.col_span; ++i) {
-    if (columns_[i + view_state.start_col]->ResizePercent() <= 0 ||
-        columns_[i + view_state.start_col]->size_type_ == GridLayout::FIXED) {
-      return false;
-    }
-  }
-  return true;
+  const auto resizable = [](const auto& col) {
+    return col->ResizePercent() > 0 && col->size_type_ != GridLayout::FIXED;
+  };
+  return std::all_of(
+      columns_.cbegin() + view_state.start_col,
+      columns_.cbegin() + view_state.start_col + view_state.col_span,
+      resizable);
 }
 
 // GridLayout -------------------------------------------------------------
@@ -787,12 +785,10 @@
 }
 
 ColumnSet* GridLayout::GetColumnSet(int id) {
-  for (const auto& column_set : column_sets_) {
-    if (column_set->id_ == id) {
-      return column_set.get();
-    }
-  }
-  return nullptr;
+  const auto i = std::find_if(
+      column_sets_.cbegin(), column_sets_.cend(),
+      [id](const auto& column_set) { return column_set->id_ == id; });
+  return (i == column_sets_.cend()) ? nullptr : i->get();
 }
 
 void GridLayout::StartRowWithPadding(float vertical_resize, int column_set_id,
@@ -1045,9 +1041,8 @@
 void GridLayout::CalculateMasterColumnsIfNecessary() const {
   if (!calculated_master_columns_) {
     calculated_master_columns_ = true;
-    for (const auto& column_set : column_sets_) {
+    for (const auto& column_set : column_sets_)
       column_set->CalculateMasterColumns();
-    }
   }
 }
 
@@ -1084,10 +1079,8 @@
 }
 
 void GridLayout::UpdateRemainingHeightFromRows(ViewState* view_state) const {
-  for (int i = 0, start_row = view_state->start_row;
-       i < view_state->row_span; ++i) {
-    view_state->remaining_height -= rows_[i + start_row]->Size();
-  }
+  view_state->remaining_height -= LayoutElement::TotalSize(
+      view_state->start_row, view_state->row_span, &rows_);
 }
 
 void GridLayout::DistributeRemainingHeight(ViewState* view_state) const {
@@ -1096,14 +1089,11 @@
     return;
 
   // Determine the number of resizable rows the view touches.
-  int resizable_rows = 0;
   int start_row = view_state->start_row;
   int max_row = view_state->start_row + view_state->row_span;
-  for (int i = start_row; i < max_row; ++i) {
-    if (rows_[i]->IsResizable()) {
-      resizable_rows++;
-    }
-  }
+  const int resizable_rows =
+      std::count_if(rows_.cbegin() + start_row, rows_.cbegin() + max_row,
+                    [](const auto& row) { return row->IsResizable(); });
 
   if (resizable_rows > 0) {
     // There are resizable rows, give the remaining height to them.
@@ -1142,11 +1132,10 @@
 }
 
 ColumnSet* GridLayout::GetLastValidColumnSet() {
-  for (int i = current_row_ - 1; i >= 0; --i) {
-    if (rows_[i]->column_set())
-      return rows_[i]->column_set();
-  }
-  return nullptr;
+  const auto i =
+      std::find_if(rows_.crend() - current_row_, rows_.crend(),
+                   [](const auto& row) { return row->column_set(); });
+  return (i == rows_.crend()) ? nullptr : (*i)->column_set();
 }
 
 }  // namespace views
diff --git a/ui/views/test/ui_controls_factory_desktop_aurax11.cc b/ui/views/test/ui_controls_factory_desktop_aurax11.cc
index b251f90..4f865802 100644
--- a/ui/views/test/ui_controls_factory_desktop_aurax11.cc
+++ b/ui/views/test/ui_controls_factory_desktop_aurax11.cc
@@ -252,15 +252,14 @@
     // doesn't rely on having a DesktopScreenX11.
     std::vector<aura::Window*> windows =
         DesktopWindowTreeHostX11::GetAllOpenWindows();
-    for (std::vector<aura::Window*>::const_iterator it = windows.begin();
-         it != windows.end(); ++it) {
-      if ((*it)->GetBoundsInScreen().Contains(point) || (*it)->HasCapture())
-        return (*it)->GetRootWindow();
-    }
-
-    NOTREACHED() << "Couldn't find RW for " << point.ToString() << " among "
-                 << windows.size() << " RWs.";
-    return nullptr;
+    const auto i =
+        std::find_if(windows.cbegin(), windows.cend(), [point](auto* window) {
+          return window->GetBoundsInScreen().Contains(point) ||
+                 window->HasCapture();
+        });
+    DCHECK(i != windows.cend()) << "Couldn't find RW for " << point.ToString()
+                                << " among " << windows.size() << " RWs.";
+    return (*i)->GetRootWindow();
   }
 
   void SetKeycodeAndSendThenMask(aura::WindowTreeHost* host,
diff --git a/ui/views/touchui/touch_selection_controller_impl_unittest.cc b/ui/views/touchui/touch_selection_controller_impl_unittest.cc
index 1a8a5315..e0532809 100644
--- a/ui/views/touchui/touch_selection_controller_impl_unittest.cc
+++ b/ui/views/touchui/touch_selection_controller_impl_unittest.cc
@@ -584,7 +584,7 @@
     // Make sure that the visible handle is being dragged.
     EXPECT_NE(visible_handle_position, textfield_->GetSelectedRange().end());
     visible_handle_position = textfield_->GetSelectedRange().end();
-    EXPECT_EQ((size_t) 10, textfield_->GetSelectedRange().start());
+    EXPECT_EQ(10u, textfield_->GetSelectedRange().start());
   }
 }
 
diff --git a/ui/views/view_model.cc b/ui/views/view_model.cc
index 438988a1..4768545b 100644
--- a/ui/views/view_model.cc
+++ b/ui/views/view_model.cc
@@ -37,14 +37,12 @@
 }
 
 void ViewModelBase::MoveViewOnly(int index, int target_index) {
-  if (index == target_index)
-    return;
   if (target_index < index) {
     View* view = entries_[index].view;
     for (int i = index; i > target_index; --i)
       entries_[i].view = entries_[i - 1].view;
     entries_[target_index].view = view;
-  } else {
+  } else if (target_index > index) {
     View* view = entries_[index].view;
     for (int i = index; i < target_index; ++i)
       entries_[i].view = entries_[i + 1].view;
@@ -60,11 +58,10 @@
 }
 
 int ViewModelBase::GetIndexOfView(const View* view) const {
-  for (size_t i = 0; i < entries_.size(); ++i) {
-    if (entries_[i].view == view)
-      return static_cast<int>(i);
-  }
-  return -1;
+  const auto i =
+      std::find_if(entries_.cbegin(), entries_.cend(),
+                   [view](const auto& entry) { return entry.view == view; });
+  return (i == entries_.cend()) ? -1 : (i - entries_.cbegin());
 }
 
 ViewModelBase::ViewModelBase() = default;
diff --git a/ui/views/view_unittest.cc b/ui/views/view_unittest.cc
index 6004845..dbca39a 100644
--- a/ui/views/view_unittest.cc
+++ b/ui/views/view_unittest.cc
@@ -71,9 +71,9 @@
 
 // Convenience functions for walking a View tree.
 const views::View* FirstView(const views::View* view) {
-  const views::View* v;
-  for (v = view; !v->children().empty(); v = v->children().front()) {
-  }
+  const views::View* v = view;
+  while (!v->children().empty())
+    v = v->children().front();
   return v;
 }
 
@@ -89,8 +89,8 @@
 // Convenience functions for walking a Layer tree.
 const ui::Layer* FirstLayer(const ui::Layer* layer) {
   const ui::Layer* l = layer;
-  while (l->children().size() > 0)
-    l = l->children()[0];
+  while (!l->children().empty())
+    l = l->children().front();
   return l;
 }
 
@@ -99,15 +99,8 @@
   if (!parent)
     return nullptr;
   const std::vector<ui::Layer*> children = parent->children();
-  size_t index;
-  for (index = 0; index < children.size(); index++) {
-    if (children[index] == layer)
-      break;
-  }
-  size_t next = index + 1;
-  if (next < children.size())
-    return FirstLayer(children[next]);
-  return parent;
+  const auto i = std::find(children.cbegin(), children.cend(), layer) + 1;
+  return (i == children.cend()) ? parent : FirstLayer(*i);
 }
 
 // Given the root nodes of a View tree and a Layer tree, makes sure the two
@@ -3478,14 +3471,14 @@
   View* child1 = new View;
   root.AddChildView(child1);
 
-  for (int i = 0; i < 2; ++i)
+  for (size_t i = 0; i < 2; ++i)
     root.AddChildView(new View);
 
   View* foo = new View;
   child1->AddChildView(foo);
 
   // Add some nodes to |foo|.
-  for (int i = 0; i < 3; ++i)
+  for (size_t i = 0; i < 3; ++i)
     foo->AddChildView(new View);
 
   EXPECT_EQ(3u, root.children().size());
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
index c401b20..ecd4604 100644
--- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
+++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
@@ -315,18 +315,16 @@
       }
     } else {
       // data.l[2,3,4] contain the first three types. Unused slots can be None.
-      for (int i = 0; i < 3; ++i) {
-        if (event.data.l[2 + i] != x11::None) {
-          unfetched_targets_.push_back(event.data.l[2 + i]);
-        }
+      for (size_t i = 2; i < 5; ++i) {
+        if (event.data.l[i] != x11::None)
+          unfetched_targets_.push_back(event.data.l[i]);
       }
     }
 
 #if DCHECK_IS_ON()
     DVLOG(1) << "XdndEnter has " << unfetched_targets_.size() << " data types";
-    for (::Atom target : unfetched_targets_) {
+    for (::Atom target : unfetched_targets_)
       DVLOG(1) << "XdndEnter data type: " << target;
-    }
 #endif  // DCHECK_IS_ON()
 
     // The window doesn't have a DesktopDragDropClientAuraX11, that means it's
@@ -448,9 +446,8 @@
 
 int DesktopDragDropClientAuraX11::X11DragContext::GetDragOperation() const {
   int drag_operation = ui::DragDropTypes::DRAG_NONE;
-  for (auto it = actions_.begin(); it != actions_.end(); ++it) {
-    MaskOperation(*it, &drag_operation);
-  }
+  for (const auto& action : actions_)
+    MaskOperation(action, &drag_operation);
 
   MaskOperation(suggested_action_, &drag_operation);
 
diff --git a/ui/views/widget/desktop_aura/desktop_screen_x11.cc b/ui/views/widget/desktop_aura/desktop_screen_x11.cc
index c0a6a9da..5fc12209 100644
--- a/ui/views/widget/desktop_aura/desktop_screen_x11.cc
+++ b/ui/views/widget/desktop_aura/desktop_screen_x11.cc
@@ -176,9 +176,9 @@
     const gfx::Point& point) const {
   if (displays_.size() <= 1)
     return GetPrimaryDisplay();
-  for (auto it = displays_.begin(); it != displays_.end(); ++it) {
-    if (it->bounds().Contains(point))
-      return *it;
+  for (const auto& display : displays_) {
+    if (display.bounds().Contains(point))
+      return display;
   }
   return *FindDisplayNearestPoint(displays_, point);
 }
@@ -187,12 +187,12 @@
     const gfx::Rect& match_rect) const {
   int max_area = 0;
   const display::Display* matching = nullptr;
-  for (auto it = displays_.begin(); it != displays_.end(); ++it) {
-    gfx::Rect intersect = gfx::IntersectRects(it->bounds(), match_rect);
+  for (const auto& display : displays_) {
+    gfx::Rect intersect = gfx::IntersectRects(display.bounds(), match_rect);
     int area = intersect.width() * intersect.height();
     if (area > max_area) {
       max_area = area;
-      matching = &*it;
+      matching = &display;
     }
   }
   // Fallback to the primary display if there is no matching display.
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
index a67ee3e..c18d5fb 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -1049,15 +1049,12 @@
   if (!dispatcher())
     return false;
 
-  aura::Window::Windows::const_iterator index;
-  for (index = window()->children().begin();
-       index != window()->children().end();
-       ++index) {
-    if ((*index)->GetProperty(aura::client::kModalKey) !=
-        ui:: MODAL_TYPE_NONE && (*index)->TargetVisibility())
-      return true;
-  }
-  return false;
+  const auto is_active = [](const auto* child) {
+    return child->GetProperty(aura::client::kModalKey) != ui::MODAL_TYPE_NONE &&
+           child->TargetVisibility();
+  };
+  return std::any_of(window()->children().cbegin(), window()->children().cend(),
+                     is_active);
 }
 
 void DesktopWindowTreeHostWin::CheckForMonitorChange() {
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
index a8aeaa8..81ef3828 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
@@ -494,10 +494,8 @@
   // If we have children, close them. Use a copy for iteration because they'll
   // remove themselves.
   std::set<DesktopWindowTreeHostX11*> window_children_copy = window_children_;
-  for (auto it = window_children_copy.begin(); it != window_children_copy.end();
-       ++it) {
-    (*it)->CloseNow();
-  }
+  for (auto* child : window_children_copy)
+    child->CloseNow();
   DCHECK(window_children_.empty());
 
   // If we have a parent, remove ourselves from its children list.
@@ -1692,8 +1690,8 @@
       display::Screen::GetScreen()->GetAllDisplays();
   // Compare against all monitor sizes. The window manager can move the window
   // to whichever monitor it wants.
-  for (size_t i = 0; i < displays.size(); ++i) {
-    if (requested_size_in_pixels == displays[i].GetSizeInPixel()) {
+  for (const auto& display : displays) {
+    if (requested_size_in_pixels == display.GetSizeInPixel()) {
       return gfx::Size(requested_size_in_pixels.width() - 1,
                        requested_size_in_pixels.height() - 1);
     }
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
index ba50a18..2578d41 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
@@ -153,11 +153,9 @@
                             int x,
                             int y) {
   gfx::Point point(x, y);
-  for (size_t i = 0; i < shape_rects.size(); ++i) {
-    if (shape_rects[i].Contains(point))
-      return true;
-  }
-  return false;
+  return std::any_of(
+      shape_rects.cbegin(), shape_rects.cend(),
+      [&point](const auto& rect) { return rect.Contains(point); });
 }
 
 }  // namespace
diff --git a/ui/views/widget/desktop_aura/x11_topmost_window_finder.cc b/ui/views/widget/desktop_aura/x11_topmost_window_finder.cc
index 4d65384..37d96bf 100644
--- a/ui/views/widget/desktop_aura/x11_topmost_window_finder.cc
+++ b/ui/views/widget/desktop_aura/x11_topmost_window_finder.cc
@@ -24,14 +24,10 @@
 
   std::vector<aura::Window*> local_process_windows =
       DesktopWindowTreeHostX11::GetAllOpenWindows();
-  bool found_local_process_window = false;
-  for (size_t i = 0; i < local_process_windows.size(); ++i) {
-    if (ShouldStopIteratingAtLocalProcessWindow(local_process_windows[i])) {
-      found_local_process_window = true;
-      break;
-    }
-  }
-  if (!found_local_process_window)
+  if (std::none_of(local_process_windows.cbegin(), local_process_windows.cend(),
+                   [this](auto* window) {
+                     return ShouldStopIteratingAtLocalProcessWindow(window);
+                   }))
     return nullptr;
 
   ui::EnumerateTopLevelWindows(this);
diff --git a/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc b/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc
index 57bc091..784577da 100644
--- a/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc
+++ b/ui/views/widget/desktop_aura/x11_topmost_window_finder_interactive_uitest.cc
@@ -77,11 +77,9 @@
   bool ShouldKeepOnWaiting(const ui::PlatformEvent& event) override {
     std::vector<XID> stack;
     ui::GetXWindowStack(ui::GetX11RootWindow(), &stack);
-    for (size_t i = 0; i < expected_windows_.size(); ++i) {
-      if (!base::ContainsValue(stack, expected_windows_[i]))
-        return true;
-    }
-    return false;
+    return !std::all_of(
+        expected_windows_.cbegin(), expected_windows_.cend(),
+        [&stack](XID window) { return base::ContainsValue(stack, window); });
   }
 
   std::vector<XID> expected_windows_;
diff --git a/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc b/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc
index 1c13481..eaf642a 100644
--- a/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc
+++ b/ui/views/widget/desktop_aura/x11_whole_screen_move_loop.cc
@@ -224,9 +224,8 @@
 
   XDisplay* display = gfx::GetXDisplay();
   unsigned int esc_keycode = XKeysymToKeycode(display, XK_Escape);
-  for (size_t i = 0; i < base::size(kModifiersMasks); ++i) {
-    XUngrabKey(display, esc_keycode, kModifiersMasks[i], grab_input_window_);
-  }
+  for (auto mask : kModifiersMasks)
+    XUngrabKey(display, esc_keycode, mask, grab_input_window_);
 
   // Restore the previous dispatcher.
   nested_dispatcher_.reset();
@@ -256,9 +255,9 @@
 void X11WholeScreenMoveLoop::GrabEscKey() {
   XDisplay* display = gfx::GetXDisplay();
   unsigned int esc_keycode = XKeysymToKeycode(display, XK_Escape);
-  for (size_t i = 0; i < base::size(kModifiersMasks); ++i) {
-    XGrabKey(display, esc_keycode, kModifiersMasks[i], grab_input_window_,
-             x11::False, GrabModeAsync, GrabModeAsync);
+  for (auto mask : kModifiersMasks) {
+    XGrabKey(display, esc_keycode, mask, grab_input_window_, x11::False,
+             GrabModeAsync, GrabModeAsync);
   }
 }
 
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc
index 1feff54..0f01bf0c 100644
--- a/ui/views/widget/widget.cc
+++ b/ui/views/widget/widget.cc
@@ -8,6 +8,7 @@
 #include <utility>
 
 #include "base/auto_reset.h"
+#include "base/containers/adapters.h"
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/strings/utf_string_conversions.h"
@@ -1422,9 +1423,8 @@
   if (child_layer_iter == root_layer->children().end())
     return true;
 
-  for (auto iter = views_with_layers.rbegin(); iter != views_with_layers.rend();
-       ++iter) {
-    ui::Layer* layer = (*iter)->layer();
+  for (View* view : base::Reversed(views_with_layers)) {
+    ui::Layer* layer = view->layer();
     DCHECK(layer);
     if (layer->visible() && layer->bounds().Contains(location)) {
       auto root_layer_iter = std::find(root_layer->children().begin(),
@@ -1438,7 +1438,6 @@
       // from the bounds of the layer. Verify the view hosting the layer
       // actually contains |location|. Use GetVisibleBounds(), which is
       // effectively what event targetting uses.
-      View* view = *iter;
       gfx::Rect vis_bounds = view->GetVisibleBounds();
       gfx::Point point_in_view = location;
       View::ConvertPointToTarget(GetRootView(), view, &point_in_view);
diff --git a/ui/views/widget/widget_interactive_uitest.cc b/ui/views/widget/widget_interactive_uitest.cc
index e8c5f2c..afd9827 100644
--- a/ui/views/widget/widget_interactive_uitest.cc
+++ b/ui/views/widget/widget_interactive_uitest.cc
@@ -801,7 +801,7 @@
 TEST_F(WidgetTestInteractive, ViewFocusOnHWNDEnabledChanges) {
   Widget* widget = CreateTopLevelFramelessPlatformWidget();
   widget->SetContentsView(new View);
-  for (int i = 0; i < 2; ++i) {
+  for (size_t i = 0; i < 2; ++i) {
     auto child = std::make_unique<View>();
     child->SetFocusBehavior(View::FocusBehavior::ALWAYS);
     widget->GetContentsView()->AddChildView(std::move(child));
diff --git a/ui/views/widget/window_reorderer.cc b/ui/views/widget/window_reorderer.cc
index a51bfaf..003f65493 100644
--- a/ui/views/widget/window_reorderer.cc
+++ b/ui/views/widget/window_reorderer.cc
@@ -10,6 +10,7 @@
 #include <map>
 #include <vector>
 
+#include "base/containers/adapters.h"
 #include "base/macros.h"
 #include "ui/aura/window.h"
 #include "ui/views/view.h"
@@ -166,9 +167,7 @@
   // |view_with_layer_order| backwards and stack windows at the bottom so that
   // windows not associated to a view are stacked above windows with an
   // associated view.
-  for (auto it = view_with_layer_order.rbegin();
-       it != view_with_layer_order.rend(); ++it) {
-    View* view = *it;
+  for (View* view : base::Reversed(view_with_layer_order)) {
     ui::Layer* layer = view->layer();
     aura::Window* window = nullptr;
 
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
index f67479a..dcdee2d 100644
--- a/ui/views/win/hwnd_message_handler.cc
+++ b/ui/views/win/hwnd_message_handler.cc
@@ -1599,14 +1599,12 @@
   delegate_->HandleDestroying();
   // If the window going away is a fullscreen window then remove its references
   // from the full screen window map.
-  for (auto iter = fullscreen_monitor_map_.Get().begin();
-       iter != fullscreen_monitor_map_.Get().end();
-       iter++) {
-    if (iter->second == this) {
-      fullscreen_monitor_map_.Get().erase(iter);
-      break;
-    }
-  }
+  auto& map = fullscreen_monitor_map_.Get();
+  const auto i = std::find_if(map.begin(), map.end(), [this](const auto& elem) {
+    return elem.second == this;
+  });
+  if (i != map.end())
+    map.erase(i);
 
   if (::switches::IsExperimentalAccessibilityPlatformUIAEnabled()) {
     // Signal to UIA that all objects associated with this HWND can be
@@ -2520,7 +2518,7 @@
   }
 
   // Handle touch events only on Aura for now.
-  int num_points = LOWORD(w_param);
+  size_t num_points = LOWORD(w_param);
   std::unique_ptr<TOUCHINPUT[]> input(new TOUCHINPUT[num_points]);
   if (ui::GetTouchInputInfoWrapper(reinterpret_cast<HTOUCHINPUT>(l_param),
                                    num_points, input.get(),
@@ -2531,7 +2529,7 @@
     TouchEvents touch_events;
     TouchIDs stale_touches(touch_ids_);
 
-    for (int i = 0; i < num_points; ++i) {
+    for (size_t i = 0; i < num_points; ++i) {
       stale_touches.erase(input[i].dwID);
       POINT point;
       point.x = TOUCH_COORD_TO_PIXEL(input[i].x);
@@ -2788,10 +2786,8 @@
 
 void HWNDMessageHandler::HandleTouchEvents(const TouchEvents& touch_events) {
   base::WeakPtr<HWNDMessageHandler> ref(msg_handler_weak_factory_.GetWeakPtr());
-  for (size_t i = 0; i < touch_events.size() && ref; ++i) {
-    ui::TouchEvent* touch_event = const_cast<ui::TouchEvent*>(&touch_events[i]);
-    delegate_->HandleTouchEvent(touch_event);
-  }
+  for (size_t i = 0; i < touch_events.size() && ref; ++i)
+    delegate_->HandleTouchEvent(const_cast<ui::TouchEvent*>(&touch_events[i]));
 }
 
 void HWNDMessageHandler::ResetTouchDownContext() {
diff --git a/ui/views/window/custom_frame_view.cc b/ui/views/window/custom_frame_view.cc
index af23de86..ad809569 100644
--- a/ui/views/window/custom_frame_view.cc
+++ b/ui/views/window/custom_frame_view.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 #include <vector>
 
+#include "base/containers/adapters.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "third_party/skia/include/core/SkPath.h"
@@ -501,13 +502,13 @@
       button_order->trailing_buttons();
 
   ImageButton* button = nullptr;
-  for (auto it = leading_buttons.begin(); it != leading_buttons.end(); ++it) {
-    button = GetImageButton(*it);
+  for (auto frame_button : leading_buttons) {
+    button = GetImageButton(frame_button);
     if (!button)
       continue;
     gfx::Rect target_bounds(gfx::Point(next_button_x, caption_y),
                             button->GetPreferredSize());
-    if (it == leading_buttons.begin())
+    if (frame_button == leading_buttons.front())
       target_bounds.set_width(target_bounds.width() + extra_width);
     LayoutButton(button, target_bounds);
     next_button_x += button->width();
@@ -516,14 +517,13 @@
 
   // Trailing buttions are laid out in a RTL fashion
   next_button_x = width() - FrameBorderThickness();
-  for (auto it = trailing_buttons.rbegin(); it != trailing_buttons.rend();
-       ++it) {
-    button = GetImageButton(*it);
+  for (auto frame_button : base::Reversed(trailing_buttons)) {
+    button = GetImageButton(frame_button);
     if (!button)
       continue;
     gfx::Rect target_bounds(gfx::Point(next_button_x, caption_y),
                             button->GetPreferredSize());
-    if (it == trailing_buttons.rbegin())
+    if (frame_button == trailing_buttons.back())
       target_bounds.set_width(target_bounds.width() + extra_width);
     target_bounds.Offset(-target_bounds.width(), 0);
     LayoutButton(button, target_bounds);
diff --git a/ui/webui/resources/cr_components/chromeos/cellular_setup/BUILD.gn b/ui/webui/resources/cr_components/chromeos/cellular_setup/BUILD.gn
index ef52aaf..aa64199 100644
--- a/ui/webui/resources/cr_components/chromeos/cellular_setup/BUILD.gn
+++ b/ui/webui/resources/cr_components/chromeos/cellular_setup/BUILD.gn
@@ -8,9 +8,13 @@
 
 js_type_check("closure_compile") {
   deps = [
+    ":base_page",
     ":button_bar",
     ":cellular_setup",
     ":mojo_interface_provider",
+    ":provisioning_page",
+    ":sim_detect_page",
+    ":success_page",
   ]
 }
 
@@ -20,10 +24,34 @@
   ]
 }
 
+js_library("base_page") {
+}
+
+js_library("sim_detect_page") {
+  deps = [
+    ":base_page",
+  ]
+}
+
+js_library("provisioning_page") {
+  deps = [
+    ":base_page",
+  ]
+}
+
+js_library("success_page") {
+  deps = [
+    ":base_page",
+  ]
+}
+
 js_library("cellular_setup") {
   deps = [
     ":button_bar",
     ":mojo_interface_provider",
+    ":provisioning_page",
+    ":sim_detect_page",
+    ":success_page",
     "//ui/webui/resources/js:i18n_behavior",
   ]
 }
diff --git a/ui/webui/resources/cr_components/chromeos/cellular_setup/base_page.html b/ui/webui/resources/cr_components/chromeos/cellular_setup/base_page.html
new file mode 100644
index 0000000..410c9791
--- /dev/null
+++ b/ui/webui/resources/cr_components/chromeos/cellular_setup/base_page.html
@@ -0,0 +1,31 @@
+<link rel="import" href="chrome://resources/html/polymer.html">
+
+<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
+
+<dom-module id="base-page">
+  <template>
+    <style>
+      #title {
+        color: var(--google-grey-900);
+        font-size: 24px;
+        font-weight: normal;
+        line-height: 24px;
+        margin: 20px 0;
+      }
+
+      #message {
+        margin-bottom: 20px;
+      }
+
+      :host ::slotted([slot='page-body']) {
+        display: block;
+        height: 500px;
+        width: 100%;
+      }
+    </style>
+    <h1 id="title">[[title]]</h1>
+    <div id="message">[[message]]</div>
+    <slot name="page-body"></slot>
+  </template>
+  <script src="base_page.js"></script>
+</dom-module>
diff --git a/ui/webui/resources/cr_components/chromeos/cellular_setup/base_page.js b/ui/webui/resources/cr_components/chromeos/cellular_setup/base_page.js
new file mode 100644
index 0000000..b31cfcd
--- /dev/null
+++ b/ui/webui/resources/cr_components/chromeos/cellular_setup/base_page.js
@@ -0,0 +1,24 @@
+// Copyright 2019 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.
+
+/** Base template with elements common to all Cellular Setup flow sub-pages. */
+Polymer({
+  is: 'base-page',
+
+  properties: {
+    /**
+     * Main title for the page.
+     *
+     * @type {string}
+     */
+    title: String,
+
+    /**
+     * Message displayed under the main title.
+     *
+     * @type {string}
+     */
+    message: String,
+  },
+});
diff --git a/ui/webui/resources/cr_components/chromeos/cellular_setup/button_bar.html b/ui/webui/resources/cr_components/chromeos/cellular_setup/button_bar.html
index 571c4c4..ae3c624b 100644
--- a/ui/webui/resources/cr_components/chromeos/cellular_setup/button_bar.html
+++ b/ui/webui/resources/cr_components/chromeos/cellular_setup/button_bar.html
@@ -13,7 +13,7 @@
       :host {
         @apply --layout-horizontal;
         @apply --layout-justified;
-        padding: 10px;
+        padding: 10px 0;
       }
     </style>
     <paper-button id="backward"
diff --git a/ui/webui/resources/cr_components/chromeos/cellular_setup/cellular_setup.html b/ui/webui/resources/cr_components/chromeos/cellular_setup/cellular_setup.html
index 389d6f9..d177739 100644
--- a/ui/webui/resources/cr_components/chromeos/cellular_setup/cellular_setup.html
+++ b/ui/webui/resources/cr_components/chromeos/cellular_setup/cellular_setup.html
@@ -3,7 +3,11 @@
 <link rel="import" href="chrome://resources/html/i18n_behavior.html">
 <link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/mojo_interface_provider.html">
 <link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/button_bar.html">
+<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/sim_detect_page.html">
+<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/provisioning_page.html">
+<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/success_page.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-pages/iron-pages.html">
 
 <dom-module id="cellular-setup">
   <template>
@@ -11,9 +15,19 @@
       :host {
         @apply --layout-flex-auto;
         @apply --layout-vertical;
+        padding: 10px;
       }
     </style>
-    <button-bar></button-bar>
+    <iron-pages attr-for-selected="is"
+        selected="[[selectedPageName_]]"
+        selected-item="{{selectedPage_}}">
+      <sim-detect-page show-error="[[showError_]]"></sim-detect-page>
+      <provisioning-page show-error="[[showError_]]"></provisioning-page>
+      <success-page show-error="[[showError_]]"></success-page>
+    </iron-pages>
+    <button-bar show-try-again-button="[[showTryAgainButton_]]"
+        show-finish-button="[[showFinishButton_]]"
+        show-cancel-button="[[showCancelButton_]]"></button-bar>
   </template>
   <script src="cellular_setup.js">
   </script>
diff --git a/ui/webui/resources/cr_components/chromeos/cellular_setup/cellular_setup.js b/ui/webui/resources/cr_components/chromeos/cellular_setup/cellular_setup.js
index ef513d7..41a7b2f 100644
--- a/ui/webui/resources/cr_components/chromeos/cellular_setup/cellular_setup.js
+++ b/ui/webui/resources/cr_components/chromeos/cellular_setup/cellular_setup.js
@@ -2,6 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+cr.define('cellular_setup', function() {
+  /** @enum{string} */
+  const PageName = {
+    SIM_DETECT: 'sim-detect-page',
+    PROVISIONING: 'provisioning-page',
+    SUCCESS: 'success-page',
+  };
+
+  return {PageName: PageName};
+});
+
 /**
  * Root element for the cellular setup flow. This element interacts with the
  * CellularSetup service to carry out the activation flow. It contains
@@ -12,6 +23,49 @@
 
   behaviors: [I18nBehavior],
 
+  properties: {
+    /**
+     * Element name of the current selected sub-page.
+     * @private {!cellular_setup.PageName}
+     */
+    selectedPageName_: {
+      type: String,
+      value: cellular_setup.PageName.SIM_DETECT,
+      notify: true,
+    },
+
+    /**
+     * DOM Element for the current selected sub-page.
+     * @private {!SimDetectPageElement|!ProvisioningPageElement|
+     *           !SuccessPageElement}
+     */
+    selectedPage_: Object,
+
+    /**
+     * Whether error state should be shown for the current page.
+     * @private {boolean}
+     */
+    showError_: {type: Boolean, value: false},
+
+    /**
+     * Whether try again should be shown in the button bar.
+     * @private {boolean}
+     */
+    showTryAgainButton_: {type: Boolean, value: false},
+
+    /**
+     * Whether finish button should be shown in the button bar.
+     * @private {boolean}
+     */
+    showFinishButton_: {type: Boolean, value: false},
+
+    /**
+     * Whether cancel button should be shown in the button bar.
+     * @private {boolean}
+     */
+    showCancelButton_: {type: Boolean, value: false}
+  },
+
   listeners: {
     'backward-nav-requested': 'onBackwardNavRequested_',
     'retry-requested': 'onRetryRequested_',
diff --git a/ui/webui/resources/cr_components/chromeos/cellular_setup/provisioning_page.html b/ui/webui/resources/cr_components/chromeos/cellular_setup/provisioning_page.html
new file mode 100644
index 0000000..c3852a9c
--- /dev/null
+++ b/ui/webui/resources/cr_components/chromeos/cellular_setup/provisioning_page.html
@@ -0,0 +1,16 @@
+<link rel="import" href="chrome://resources/html/polymer.html">
+
+<link rel="import" href="chrome://resources/html/i18n_behavior.html">
+<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/base_page.html">
+
+<dom-module id="provisioning-page">
+  <template>
+    <base-page title="[[i18n('provisioningPageTitle')]]">
+      <div slot="page-body">
+        <!-- TODO(azeemarshad): Add webview and error screen -->
+        [[i18n('provisioningPageTitle')]]
+      </div>
+    </base-page>
+  </template>
+  <script src="provisioning_page.js"></script>
+</dom-module>
diff --git a/ui/webui/resources/cr_components/chromeos/cellular_setup/provisioning_page.js b/ui/webui/resources/cr_components/chromeos/cellular_setup/provisioning_page.js
new file mode 100644
index 0000000..8c89b909
--- /dev/null
+++ b/ui/webui/resources/cr_components/chromeos/cellular_setup/provisioning_page.js
@@ -0,0 +1,26 @@
+// Copyright 2019 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.
+
+/**
+ * Carrier Provisioning subpage in Cellular Setup flow. This element contains a
+ * webview element that loads the carrier's provisioning portal. It also has an
+ * error state that displays a message for errors that may happen during this
+ * step.
+ */
+Polymer({
+  is: 'provisioning-page',
+
+  behaviors: [I18nBehavior],
+
+  properties: {
+    /**
+     * Whether error state should be shown.
+     * @type {boolean}
+     */
+    showError: {
+      type: Boolean,
+      value: false,
+    },
+  },
+});
diff --git a/ui/webui/resources/cr_components/chromeos/cellular_setup/sim_detect_page.html b/ui/webui/resources/cr_components/chromeos/cellular_setup/sim_detect_page.html
new file mode 100644
index 0000000..1cde306
--- /dev/null
+++ b/ui/webui/resources/cr_components/chromeos/cellular_setup/sim_detect_page.html
@@ -0,0 +1,16 @@
+<link rel="import" href="chrome://resources/html/polymer.html">
+
+<link rel="import" href="chrome://resources/html/i18n_behavior.html">
+<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/base_page.html">
+
+<dom-module id="sim-detect-page">
+  <template>
+    <base-page title="[[i18n('simDetectPageTitle')]]">
+      <div slot="page-body">
+        <!-- TODO(azeemarshad): Add page assets and strings -->
+        [[i18n('simDetectPageTitle')]]
+      </div>
+    </base-page>
+  </template>
+  <script src="sim_detect_page.js"></script>
+</dom-module>
diff --git a/ui/webui/resources/cr_components/chromeos/cellular_setup/sim_detect_page.js b/ui/webui/resources/cr_components/chromeos/cellular_setup/sim_detect_page.js
new file mode 100644
index 0000000..8f6357dc
--- /dev/null
+++ b/ui/webui/resources/cr_components/chromeos/cellular_setup/sim_detect_page.js
@@ -0,0 +1,26 @@
+// Copyright 2019 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.
+
+/**
+ * SIM Detection subpage in Cellular Setup flow. This element contains image
+ * asset and description to indicate that the SIM detection is in progress.
+ * It also has an error state that displays a message for errors that may
+ * happen during this step.
+ */
+Polymer({
+  is: 'sim-detect-page',
+
+  behaviors: [I18nBehavior],
+
+  properties: {
+    /**
+     * Whether error state should be shown.
+     * @type {boolean}
+     */
+    showError: {
+      type: Boolean,
+      value: false,
+    },
+  }
+});
diff --git a/ui/webui/resources/cr_components/chromeos/cellular_setup/success_page.html b/ui/webui/resources/cr_components/chromeos/cellular_setup/success_page.html
new file mode 100644
index 0000000..572c8212
--- /dev/null
+++ b/ui/webui/resources/cr_components/chromeos/cellular_setup/success_page.html
@@ -0,0 +1,17 @@
+<link rel="import" href="chrome://resources/html/polymer.html">
+
+<link rel="import" href="chrome://resources/html/i18n_behavior.html">
+<link rel="import" href="chrome://resources/cr_components/chromeos/cellular_setup/base_page.html">
+
+<dom-module id="success-page">
+  <template>
+    <base-page title="[[i18n('successPageTitle')]]"
+        message="[[i18n('successPageMessage')]]">
+      <div slot="page-body">
+        <!-- TODO(azeemarshad): Add page assets and strings -->
+        [[i18n('successPageTitle')]]
+      </div>
+    </base-page>
+  </template>
+  <script src="success_page.js"></script>
+</dom-module>
diff --git a/ui/webui/resources/cr_components/chromeos/cellular_setup/success_page.js b/ui/webui/resources/cr_components/chromeos/cellular_setup/success_page.js
new file mode 100644
index 0000000..99b745d
--- /dev/null
+++ b/ui/webui/resources/cr_components/chromeos/cellular_setup/success_page.js
@@ -0,0 +1,13 @@
+// Copyright 2019 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.
+
+/**
+ * Final success page in Cellular Setup flow. This element contains image
+ * asset and description that indicates that the setup flow has completed.
+ */
+Polymer({
+  is: 'success-page',
+
+  behaviors: [I18nBehavior]
+});
diff --git a/ui/webui/resources/cr_components/cr_components_resources.grdp b/ui/webui/resources/cr_components/cr_components_resources.grdp
index 3556f5d..02e49b0 100644
--- a/ui/webui/resources/cr_components/cr_components_resources.grdp
+++ b/ui/webui/resources/cr_components/cr_components_resources.grdp
@@ -284,6 +284,38 @@
                file="cr_components/chromeos/cellular_setup/button_bar.js"
                type="chrome_html"
                compress="gzip" />
+    <structure name="IDR_WEBUI_CHROMEOS_CELLULAR_SETUP_BASE_PAGE_HTML"
+               file="cr_components/chromeos/cellular_setup/base_page.html"
+               type="chrome_html"
+               compress="gzip" />
+    <structure name="IDR_WEBUI_CHROMEOS_CELLULAR_SETUP_BASE_PAGE_JS"
+               file="cr_components/chromeos/cellular_setup/base_page.js"
+               type="chrome_html"
+               compress="gzip" />
+    <structure name="IDR_WEBUI_CHROMEOS_CELLULAR_SETUP_SIM_DETECT_PAGE_HTML"
+               file="cr_components/chromeos/cellular_setup/sim_detect_page.html"
+               type="chrome_html"
+               compress="gzip" />
+    <structure name="IDR_WEBUI_CHROMEOS_CELLULAR_SETUP_SIM_DETECT_PAGE_JS"
+               file="cr_components/chromeos/cellular_setup/sim_detect_page.js"
+               type="chrome_html"
+               compress="gzip" />
+    <structure name="IDR_WEBUI_CHROMEOS_CELLULAR_SETUP_PROVISIONING_PAGE_HTML"
+               file="cr_components/chromeos/cellular_setup/provisioning_page.html"
+               type="chrome_html"
+               compress="gzip" />
+    <structure name="IDR_WEBUI_CHROMEOS_CELLULAR_SETUP_PROVISIONING_PAGE_JS"
+               file="cr_components/chromeos/cellular_setup/provisioning_page.js"
+               type="chrome_html"
+               compress="gzip" />
+    <structure name="IDR_WEBUI_CHROMEOS_CELLULAR_SETUP_SUCCESS_PAGE_HTML"
+               file="cr_components/chromeos/cellular_setup/success_page.html"
+               type="chrome_html"
+               compress="gzip" />
+    <structure name="IDR_WEBUI_CHROMEOS_CELLULAR_SETUP_SUCCESS_PAGE_JS"
+               file="cr_components/chromeos/cellular_setup/success_page.js"
+               type="chrome_html"
+               compress="gzip" />
 
     <!-- Shared between MultiDevice setup flow and OOBE. -->
     <structure name="IDR_WEBUI_CHROMEOS_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_BROWSER_PROXY_HTML"